从今日头条上看到了一道考察Java类加载机制的基础题,感觉不错,只是没有看到答案,所以自己手动敲了一下代码,现将其整理如下:
题目
1.父类A、子类B(继承自父类A)、程序入口类C
public class HelloA {
public HelloA() {
System.out.println("父类A 构造方法");
}
{ System.out.println("父类A 构造代码块"); }
static { System.out.println("父类A 静态方法"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("子类B 构造方法");
}
{ System.out.println("子类B 构造代码块"); }
static { System.out.println("子类B 静态方法"); }
}
//程序入口类
public class HelloC {
public static void main(String[] args){
System.out.println("-----------main start-----------");
new HelloB();
System.out.println("-----------main end-------------");
}
}
运行结果如下:
-----------main start-----------
父类A 静态方法
子类B 静态方法
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------
2.父类A、子类B(继承自父类A),程序入口在B类中
public class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class."); }
static { System.out.println("Static A"); }
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class."); }
static { System.out.println("Static B"); }
public static void main(String[] args){
System.out.println("-----------main start-----------");
new HelloB();
System.out.println("-----------main end-------------");
}
}
运行结果如下:
父类A 静态方法
子类B 静态方法
-----------main start-----------
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------
3.父类A、子类B(继承自父类A),程序入口在A类中
public class HelloA {
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class."); }
static { System.out.println("Static A"); }
public static void main(String[] args){
System.out.println("-----------main start-----------");
new HelloB();
System.out.println("-----------main end-------------");
}
}
public class HelloB extends HelloA {
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class."); }
static { System.out.println("Static B"); }
}
运行结果如下:
父类A 静态方法
-----------main start-----------
子类B 静态方法
父类A 构造代码块
父类A 构造方法
子类B 构造代码块
子类B 构造方法
-----------main end-------------
简单总结:
1.实例化子类的时候
(1)若此类未被加载过,首先加载是父类的类对象,然后加载子类的类对象,接着实例化父类,最后实例化子类;
(2)若此类被加载过,不再加载父类和子类的类对象。
2.接下来是加载顺序
(1)当加载类对象时,首先初始化静态属性,然后执行静态块;
(2)当实例化对象时,首先执行构造块(直接写在类中的代码块),然后执行构造方法。
(3)如果存在多个静态块,各静态块之间执行的顺序按代码先后;如果存在多个静态属性,各静态属性初始化的顺序按代码先后。
(4)属性、构造块(也就是上面的实例块)、构造方法之间的执行顺序(但构造块一定会在构造方法前执行),也是按代码的先后顺序。
3.还要注意入口函数位置、类的执行顺序;
本人java小白,有错误还请指出,共同学习...
参考资料:
(1)Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序
https://www.cnblogs.com/chihirotan/p/6043442.html
(2)一道网易Java工程师面试题看出你对Java类加载机制的理解深浅
http://url.cn/57lX6cG
网友评论