前言:
说下这篇文章的来龙去脉:昨天接到了阿里小哥哥的面试电话,小哥哥问我jvm加载类的过程。然后我巴拉巴拉说了一堆classLoader装载类的过程。然后小哥哥说我不是要问这些。。。好吧装载加载傻傻分不清楚。
jvm加载类过程(本人不会,以下内容由小哥哥解释给我听的):
- classLoader装载类
- 连接(包括验证,准备,解析:小哥哥详述了这三个步骤。。因为我比较疑问哈哈哈)
- 初始化 (小哥哥开始问我这个具体初始化过程)
( 本人其实脑子一片浆糊,很多概念傻傻分不清除)比如:类的初始化和对象的实例化
类的初始化:主要是类静态变量的赋值,静态代码块的执行过程。即执行<clinit>:类构造器<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态代码块static{}中的语句合并产生的,其中编译器收集的顺序是由语句在源文件中出现的顺序所决定。<clinit>只会执行一次。
对象的实例化:主要是实例变量(非静态变量),非静态代码块,构造函数的实例过程。即执行<init>:实例构造器<init>()是指收集类中的所有实例变量的赋值动作、实例代码块和构造函数合并产生的。<init>执行多次,毕竟有时候实例化多个对象嘛
(因为本人傻傻讲不清除,小哥哥就具体问:父类的静态变量,非静态变量,子类的静态变量,非静态变量的赋值(实例化)顺序,本人开始胡诌,回答的完全错误)
父类的静态变量,非静态变量,子类的静态变量,非静态变量的赋值(实例化)顺序:(刚刚搜出来的答案)
父类静态变量/静态块(顺序执行)->子类静态变量/静态块(顺序执行)->父类实例变量/构造块(顺序执行)->父类构造器->子类实例变量/构造块(顺序执行)->子类构造器
so,先初始化父类,再初始化子类,接着实例化父类,生成父类对象,然后实例化子类,生成子类对象。
( 这个问题结束后,小哥哥说这个我还是需要了解的,以后写代码不知道过程出错了咋办呢)
补充(以前的笔记,摘自某篇博客具体来源忘了):
1、验证:验证被加载后的类是否有正确的结构,类数据是否会符合虚拟机的要求,确保不会危害虚拟机安全。
2、准备:为类的静态变量(static filed)在方法区分配内存,并赋默认初值(0值或null值)。如static int a = 100;
静态变量a就会在准备阶段被赋默认值0。
对于一般的成员变量是在类实例化时候,随对象一起分配在堆内存中。
另外,静态常量(static final filed)会在准备阶段赋程序设定的初值,如static final int a = 666; ?静态常量a就会在准备阶段被直接赋值为666,对于静态变量,这个操作是在初始化阶段进行的。
3、解析:将类的二进制数据中的符号引用换为直接引用。
解析
将常量池中所有的符号引用转为直接引用(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法)。这个阶段可以在初始化之后再执行。
PS:小哥哥在面试过程中基本上把每个答案都给我解释一遍,超温柔,声音超好听。。。。。。。最后还给我解答了我最近很迷茫的问题,跪谢~~~
原文地址:https://www.cnblogs.com/cai-cai777/p/10921770.html