目录
创作背景:
用"创作"背景这个词总感觉有些怪怪的,搞得这些结论是自己一手发现的...但无论如何,写这篇文章的目的一是能让自己复习类初始化的流程,整理一下知识点;另一方面如果能帮助到有困惑的人那当然是更好了。
首先,先说说这篇文章的动机:前几天在复习javaSE的时候,刚好有说到创建对象的过程,所以借着这个机会刚好把这些知识做一个整理,然后也算是加深理解吧。(给大家一个建议,就是平常学习完之后可以用口述或者写文字的形式再把知识复述出来,在这个过程中找到盲点简直so easy!)
new 类()的时候究竟发生了啥?
package Student;
public class StudentDemo {
public static void main(String[] args){
Student s1 = new Student();
}
}
我们在学习面向对象的时候,一开始接触的就是new一个对象,以至于我们对这个行为已经习以为常。但如果我们深入一点还是能发现有很多点值得我们去学习的。我们知道创建一个对象的过程是先将jdc将java文件(就是我们写的源代码)编译成.class文件(这里注意的是:编译其实就是我们按ctrl+s的时候就已经完成了),然后通过jvm运行,那么更详细的流程是怎么样的呢?
那当代码中有一段Student s = new Student()时,整个程序的流程是什么呢?
(---图片摘自知乎博主bravo1988)
这里有几个要注意的点:
- ClassLoader加载字节码文件到内存之后,每个类会只生成一个Class对象(注意是每个类不是每个对象),而这个Class对象包含了成员方法,成员变量,注解...等等一系列你能想到的玩意这里面都包含了!而这个Class对象就是反射得以实现的基础。
- 静态方法,静态变量随类的加载而加载,因此是使用不了非静态的成员变量和方法的。
- ClassLoader采用双亲委托机制,这个机制目的就是防止我们写一些“旁门左道”的类,如"手撕"String类,ArrayList类等等,主打一个安全二字!
在第一步.class文件加载到内存之后,并且在堆中申请内存空间后,内存里面的繁荣景象是这样的:
当然,内存实际是不分这些区域(堆,栈,方法区)的,这样只是为了让我们更好理解。同时,方法区所包含的内容也不仅仅只有画的三块区域,具体的内容请见:Java虚拟机(JVM)的方法区(Method Area)存储了什么内容?
在指向内存中的区域后,jvm首先对Student的成员变量赋初值(引用类型为null,int类型为0....),待执行构造方法or成员方法时进行赋值。
儿子继承父亲时,new Zi()的代码执行顺序?
和刚刚的类似,也是先将父.class和子.class文件加载到内存中,之后的流程便是:
- 初始化父类静态修饰的字段 (初始化的目的是为了赋实实在在的值)
- 初始化子类静态修饰的字段
- ①:初始化父类普通字段 ②:初始化父类构造方法 (之所以父类在前是因为继承的缘故,初始化父类子类便能得到许多相同的数据,子类不必再创建)
- ①:初始化子类普通字段 ②:初始化子类构造方法
以上为文章的全部内容,因为博主水平确实不太高,如果有错误的地方,还烦请指出错误!
参考资料:
1.刘意javaSE2014教程
3.bravo1988《super、static、final关键字》