java 中类与对象的加载顺序

本贴最后更新于 2430 天前,其中的信息可能已经天翻地覆

1. 何时会初始化类?


  • 主动 new
  • 调用类的静态方法
  • 操作类或接口的静态属性或者为其赋值
  • 反射操作
  • 指定一个类作为 Java 虚拟机启动时的初始化类。
  • 初始化一个类的子类 同样会初始化它的父类

以上均为初始化类的手段。


2. 加载顺序是什么?

创建两个类:父类 Parent,子类 Child 继承父类 Parent 用于演示初始化子类时对父类的影响。

public class Parent {

	static String parenntName = "Parent";

	Integer age = 18;

	static {
		System.out.println("父类静态代码块。。。" + parenntName);
	}

	{
		System.out.println("父类代码块。。。");
		System.out.println(age);
	}

	public static void print() {
		System.out.println("父类静态方法。。。" + parenntName);
	}

	public Parent(String content) {
		System.out.println(age);
		System.out.println("父类带参构造方法。。。");
	}

	public Parent() {
		System.out.println("父类构造方法。。。");
	}
	
}
public class Child extends Parent {

	static String childName = "Child";

	static {
		System.out.println("子类静态代码块。。。" + childName);
	}

	{
		System.out.println("子类代码块。。");
	}

	public Child() {
		System.out.println("子类构造方法。。。");
	}

	
	public Child(String name) {
		System.out.println("子类带参构造方法。。。");
	} 
}

2.1 然后写一个 main 方法 new Parent(),执行以后,输出的结果如下:

父类静态代码块。。。Parent
父类代码块。。。
18
父类构造方法。。。

这里可以看出来代码的执行顺序:先初始化静态变量 -> 静态代码块 -> 成员变量 -> 代码块 -> 构造方法

2.2 new Child() 试试:

父类静态代码块。。。Parent
子类静态代码块。。。Child
父类代码块。。。
18
父类构造方法。。。
子类代码块。。
子类构造方法。。。

执行顺序:先初始化父类静态变量 -> 父类静态代码块 -> 子类静态变量 -> 子类静态代码块 -> 父类成员变量 -> 父类代码块 -> 父类构造方法 -> 子类成员变量 -> 子类代码块 -> 子类构造方法

2.3 试试调用类的静态方法 Parent.print(),看看会怎么样:

父类静态代码块。。。Parent
父类静态方法。。。Parent

执行顺序:先执行静态变量 -> 静态代码块 -> 静态方法

2.4 操作类或接口的静态属性或者为其赋值 Parent.parenntName = "jack"

父类静态代码块。。。Parent

执行顺序:先执行静态变量 -> 静态代码块
PS:这里如果用 Child 去操作父类的静态方法或者静态属性效果是一样的。

2.5 使用有参构造 new Child("pleuvoir"),结果如下:

父类静态代码块。。。Parent
子类静态代码块。。。Child
父类代码块。。。
18
父类构造方法。。。
子类代码块。。
子类带参构造方法。。。

显然这里和直接 new Child() 的结果类似,唯一不同的是最后执行的是子类带参构造方法,让我惊奇的是父类也有类似的有参构造方法,实例化子类时 JVM 默认调用的是父类的无参构造方法。也就是说子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。

3. 结论

静态属性和静态代码块只会执行一次
静态属性 > 静态代码块 > 成员变量 > 代码块 > 构造方法
静态内容:静态属性和静态代码块(静态属性先于静态代码块)
普通内容:成员变量和代码块(成员变量先于代码块)
首先执行父类静态内容,然后执行子类静态内容,接着父类普通内容,父类构造函数,子类普通内容,子类构造函数
如果调用类的静态属性或者静态方法会执行实际执行类的静态内容

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3453 回帖 • 203 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...