先看看几个类
public class Animal {
public Body b1 = new Body("Animal b1");
public static Body b2 = new Body("Animal static b2");
public Animal(){
Body b3 = new Body("Animal b3");
System.out.println("Animal create..");
}
}
public class Dog extends Animal{
public Body b1 = new Body("Dog b1");
public static Body b2 = new Body("Dog static b2");
public static final Body b3 = new Body("Dog static final b3");
public static int a = 5;
public static final int b = 6;
public Dog(){
Body b4 = new Body("Dog b4");
System.out.println("Dog create..");
}
}
public class Body {
public Body(String name){
System.out.println(name+"loading");
}
}
首先执行第一种测试
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
}
}
这一种新建了一个dog,当类进行加载的时候,首先是进行父类的加载。
1,所以当创建Dog的时候,检查存在父类进行加载父类
所以父类中的静态变量都会被初始化,所以静态方法全部执行,而不是静态方法在他们之后初始化
然后是加载子类,然后Dog的静态变量会被初始化,同时final的也被初始化
2,这个时候开始调用子类的构造方法,默认会调用父类的构造方法,在构造方法之前要先初始化变量b1,所以就创建Body了
所有的变量初始化后,就继续调用父类的构造方法b3被创建。打印Animal create
3,父类的调用完之后调用子类的构造器,先初始化变量b1,然后打印
执行结果:
Animal static b2loading
Dog static b2loading
Dog static final b3loading
Animal b1loading
Animal b3loading
Animal create..
Dog b1loading
Dog b4loading
Dog create..
第二种测试,什么情况加载类
public static void main(String[] args) {
try {
Class.forName("cn.dzq.loading.Dog");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
当Class加载Dog的时候会先加载父类,所以先初始化父类的静态属性,然后初始化子类的属性
执行结果:
Animal static b2loading
Dog static b2loading
Dog static final b3loading
第二种测试,使用类名直接调用属性的时候是否加载
public static void main(String[] args) {
System.out.println(Dog.b3);
}
这样会加载Dog类
执行结果:
Animal static b2loading
Dog static b2loading
Dog static final b3loading
cn.dzq.loading.Body@ca0b6
直接调用static的基本数据类型
public static void main(String[] args) {
System.out.println(Dog.a);
}
同样会加载Dog类
执行结果:
Animal static b2loading
Dog static b2loading
Dog static final b3loading
5
直接调用static final的基本数据类型
public static void main(String[] args) {
System.out.println(Dog.b);
}
就不会直接加载类
执行结果:
6
以上全是自己总结,如果有错误的地方可以直接提出来,或者有更好的思路都可以说说。