java类加载及初始化
继承时java静态变量及实例变量初始化
最近在读《JAVA编程思想》,真是精彩呀,棒极了!没有看过的必须要看呀!!!不过七百多页,一天看上一二十页,坚持住!
不过作者一个案例几十行代码,还全是英文的,就像隔了一层雾,总是看的不真切。这是我在书中代码的基础上,添加了一些验证自己疑惑的代码,总算理顺了java初始化的过程。话不多说,直接看代码。
父类(基类)
package read.book.test;
public class Inset {
private int a =31;
protected int b;
protected int c;
protected int d = printInit("5.0、基类定义初始化,在4之后,5以前");
{
System.out.println("5、基类实例初始化,a=" +a + ",b=" +b + ",c=" +c);
b= 32;
System.out.println("5.1、基类实例初始化结束,a=" +a + ",b=" +b + ",c=" +c);
}
Inset() {
System.out.println("6、基类构造初始化");
c = 33;
System.out.println("6.1、基类构造初始化结束,a=" +a + ",b=" +b + ",c=" +c);
}
private static int x = printInit("1、基类静态变量 --X 初始化");
static int printInit(String s) {
System.out.println(s);
return 47;
}
static {
System.out.println("2、基类静态代码块初始化(定义顺序在1之后,所以初始化在1之后)");
y =88;
}
static int y;
}
子类(导出类)
package read.book.test;
/**
* @author
* @desc 验证类的加载过程
* 1、基类的实例初始化+构造初始化 整体上:先于导出类的实例初始化和构造初始化
* 2、默认初始化、定义初始化在实例初始化之前,是不是也整体先于导出类定义初始化、实例初始化呢?
* @createTime 2019/11/26 14:13
**/
public class Beetle extends Inset {
private int i = 6;
private int k ;
// private int l = printInit("7、子类定义初始化i=" + i+",k=" + k + ",m=" + m);//illegal forwar reference
private int l = printInit("7、子类定义初始化i=" + i+",k=" + k + "由于m在下一行才定义," +
"所以无法打印m的值;而k为0,说明已经默认初始化");
private int m;
{
k = 7;
System.out.println("8、子类实例初始化,i=" + i+",k=" + k + ",l=" +l + ",m=" + m);
}
public Beetle() {
System.out.println("9、子类构造方法中,i=" + i+",k=" + k + ",l=" +l + ",m=" + m);
// System.out.println("a=" + a); private 子类访问不到
m =8;
System.out.println("9.1、子类构造方法结束,i=" + i+",k=" + k + ",l=" +l + ",m=" + m);
}
private static int x2 = printInit("3、子类静态初始化");
static int printInit(String s) {
System.out.println(s);
return 10;
}
public static void main(String[] args) {
System.out.println("4、基类、导出类静态变量初始化之后,准备创建子类对象了--main方法中");
System.out.println("--------以下为实例化过程");
Beetle beetle = new Beetle();//注释掉这1行,则不会创建对象
System.out.println("\n 总结:\n" +
"以4为分界线,4之前加载class文件到内存中初始化静态变量,4之后开始分配内存,创建对象:\n" +
"1、静态域初始化,先初始化父类的静态域,再初始化子类静态域 \n" +
"2、父类对象初始化:,对父类实例变量分别进行:默认初始化(基本类型为0,引用类型为null)、定义初始化(变量赋值)、实例初始化({}中,不带任何关键字)、构造初始化\n" +
"3、子类对象初始化:依次执行默认、定义、实例、构造等初始化过程");
}
}
运行结果
1、基类静态变量 --X 初始化
2、基类静态代码块初始化(定义顺序在1之后,所以初始化在1之后)
3、子类静态初始化
4、基类、导出类静态变量初始化之后,准备创建子类对象了--main方法中
--------以下为实例化过程
5.0、基类定义初始化,在4之后,5以前
5、基类实例初始化,a=31,b=0,c=0
5.1、基类实例初始化结束,a=31,b=32,c=0
6、基类构造初始化
6.1、基类构造初始化结束,a=31,b=32,c=33
7、子类定义初始化i=6,k=0由于m在下一行才定义,所以无法打印m的值;而k为0,说明已经默认初始化
8、子类实例初始化,i=6,k=7,l=10,m=0
9、子类构造方法中,i=6,k=7,l=10,m=0
9.1、子类构造方法结束,i=6,k=7,l=10,m=8
总结:
以4为分界线,4之前加载class文件到内存中初始化静态变量,4之后开始分配内存,创建对象:
1、静态域初始化,先初始化父类的静态域,再初始化子类静态域
2、父类对象初始化:,对父类实例变量分别进行:默认初始化(基本类型为0,引用类型为null)、定义初始化(变量赋值)、实例初始化({}中,不带任何关键字)、构造初始化
3、子类对象初始化:依次执行默认、定义、实例、构造等初始化过程