一、代码如下
1、创建一个Father类,包含实例变量、静态变量、静态代码块、构造方法、构造代码块、实例方法、静态方法
**@Description: 理解类的加载机制
* @version v1.0
* @author w
* @date 2021年8月14日上午8:58:24
*/
public class Father {
// 实例变量
private int i = test();
// 静态变量
private static int x = method();
// 静态代码块
static {
System.out.println("Father: 1");
}
// 构造方法
public Father() {
System.out.println("Father: 2");
}
//构造代码块
{
System.out.println("Father: 3");
}
// 实例方法
public int test() {
System.out.println("Father: 4");
return 666;
}
// 静态方法
private static int method() {
System.out.println("Father: 5");
return 777;
}
}
2、创建一个Son类,继承Father类
/**@Description: 理解类的加载顺序
* @version v1.0
* @author w
* @date 2021年8月14日上午9:02:58
*/
public class Son extends Father {
private int i = test();
private static int x = method();
static {
System.out.println("Son: 6");
}
public Son() {
System.out.println("Son: 7");
}
{
System.out.println("Son: 8");
}
public int test() {
System.out.println("Son: 9");
return 888;
}
private static int method() {
System.out.println("Son: 10");
return 999;
}
}
二、开始测试
1、在 Son类中,写一个main方法,直接运行:
public static void main(String[] args) {}
// 输出结果为:
Father: 5
Father: 1
Son: 10
Son: 6
1.1、main方法,所在的类,会被初始化加载 --- 加载父类静态方法、静态块;再加载子类静态方法、静态块。(注意:静态方法、静态块,是自上而下的加载,不会优先加载静态块,可通过静态块和静态变量位置,进行测试理解)
2、在Son类中,main方法加上2行代码:
public static void main(String[] args) {
Son s = new Son();
Son s2 = new Son();
}
2.1、输出结果如下:
Father: 5
Father: 1
Son: 10
Son: 6
// 这里注释是人工添加,非程序输出结果
Son: 9
Father: 3
Father: 2
Son: 9
Son: 8
Son: 7
// 这里注释是人工添加,非程序输出结果
Son: 9
Father: 3
Father: 2
Son: 9
Son: 8
Son: 7

2.2、输出分析:
- 1-4行:为静态方法输出,先Father类,后Son类
- 6-11行:为实例化对象输出,6-8行为Father类,9-11行为Son类
- 13-18行:同6-11行
2.3、结果分析:
- 程序中,创建了2个对象,分别为s和s2,静态方法部分,只输出一次
- 创建对象时,先初始化Father类,再初始化Son类 (和静态加载顺序一致)
- Father类加载顺序为:实例方法和构造代码块 按照先后顺序加载,构造方法最后加载 (可通过调整: 实例变量 和 构造代码块的位置理解)
- 其中第六行:输出为 Son: 9 ;说明调用的Son类的test方法,原因是 Son类的test方法,重写了Father类的test方法,只是省略了 @Override 注解。(多态:运行看右边 --- 子类)
三、总结
1、main方法,所在的类,会被初始化加载。
2、类的加载机制:先父类,后子类;静态部分,只加载一次;加载顺序:(静态块、静态方法)自上而下。
3、类的初始化机制:先父类,后子类;创建一个对象,则初始化一次;加载顺序:实例方法 和 构造代码块 自上而下 ,构造方法 最后加载。
4、多态的机制:子类重写父类方法后,默认会执行子类方法(省略当前对象this,要调用父类方法需要用 super)。(编译看左边(父类、接口),运行看右边(子类))
5、静态方法:不能被重写,因为是随类的加载时而加载的。
6、关于方法重写:若父类方法用 private 或 final 、static 修饰 ,则不能被子类重写。
本文详细探讨了Java中的类加载机制,包括静态和实例部分的加载顺序,以及对象创建时的初始化过程。通过Father和Son类的例子,展示了静态方法和静态块的加载是从上到下,而实例方法、构造代码块和构造方法的加载顺序则是根据定义的顺序。此外,文章还解释了多态的概念,强调在子类重写父类方法时,运行时会调用子类的方法。总结了类加载和初始化的关键点,并提到了方法重写的相关规则。
972

被折叠的 条评论
为什么被折叠?



