Java类初始化的时机

本文详细解析了Java虚拟机在不同场景下初始化类的过程,包括main方法调用、new指令、静态方法及变量调用、子类初始化、反射调用以及接口实现时的类加载顺序。通过具体代码示例,深入理解类加载的触发条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.当虚拟机启动时,加载用户指定的main方法所在的类。

2.当在main方法遇到了new关键字时,初始化new指令的目标类。

3.当遇到静态方法调用时,初始化静态方法所在的类。

4.当遇到静态变量调用时,初始化静态变量所在的类。

5.子类的初始化时会先触发父类的初始化。

6.使用反射调用某个类时,会初始化该类。

7.如果一个类直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化。

注意

1.当子类去引用父类的静态变量时,父类会被加载,子类不会。
2.会先初始化main方法所在的类
3.当用数组创建类是并不会初始化该类,但是会将该类加载进内存。
4.如果去调用一个类中static final修饰的常量则不会加载该类,而是直接从常量池中将常量取出。

测试:

执行class文件时,可以通过JVM参数 -verbose:class 查看类加载的先后顺序。

测试第一条和第二条。

public class TestClassLoader{
	public static void main(String[] args){
		Demo1 demo1 = new Demo1();
	}
}

public class Demo1{
	
	
}

测试第三条。

public class TestClassLoader{
	public static void main(String[] args){
		Demo1.method();
	}
}


public class Demo1{
	
	public static void method(){
		
	}
}

第四条跟第三条差不多就不测试了。

测试第五条,会先初始化父类,在初始化子类。

public class TestClassLoader extends Parent{
	public static void main(String[] args){
		
	}
}


public class Parent {
	
}

测试第6条。

public class TestClassLoader{
	public static void main(String[] args){
		try{
			//注意,要先将Demo1编译为class文件才能调用到! 
			Class clazz = Class.forName("Demo1");
		}catch(ClassNotFoundException e){
			
		}
	}
}

测试第7条,先初始化实现的接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值