类加载机制之触发类初始化情景验证

类加载的过程

  1. 加载 :从class,jar,war等加载字节码,在方法区创建CLASS对象
  2. 验证 : JVM规划检验,代码逻辑校验
  3. 准备 :为类变量【静态变量】分配空间,赋初值,为常量赋值
  4. 解析 :解析类的接口,方法,类,属性
  5. 初始化:执行静态代码块与为静态变量赋值
  6. 使用: 创建实例对象
  7. 卸载: 从JVM方法区中卸载

什么情况下不会触发类初始化

1.通过子类调用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化
2.定义对象数组,不会触发该类的初始化
3.调用类的常量,常量在编译期间会存入调用类的常量池中,本质上并未直接引用定义常量的类,不会触发定义常量所在的类
4.通过类名获取Class对象
5.通过class.forname()方法获取类对象时,指定初始化参数为false;
6.通过ClassLoader默认的loadClass方法加载类

验证1

public class ClassInit1 {

	public static void main(String[] args) {
	
		System.out.println("父亲的年龄: "+son.FatherAge);
	}
}
class son extends father
{
	static
	{
 
		System.out.println("子类的静态代码块执行,代表类初始化");
	}
}

class father
{

	static 
	{
	
		System.out.println("父类的静态代码块执行,代表类初始化");
	}	

	public static int FatherAge = 36;
}

输出结果:
父类的静态代码块执行,代表类初始化
父亲的年龄: 36

验证2

public class ClassInit1 {

public static void main(String[] args) {
	
		father[] a = new father[1];

	}
}
class father
{

	static 
	{
	
		System.out.println("父类的静态代码块执行,代表类初始化");
	}	

	public static int FatherAge = 36;
}

无输出

验证3

class father
{

	static 
	{
		
		System.out.println("父类的静态代码块执行,代表类初始化");
	}
	
	public static int FatherAge = 36;
	public final static int BIRTH_MONTH = 1;
}
public class ClassInit1 {

	public static void main(String[] args) {
	
		System.out.println("父亲的生日月份: "+ father.BIRTH_MONTH);
	}
}

输出结果:
父亲的生日月份: 1

验证4:

public class ClassInit1 {

public static void main(String[] args) {
	try 
	{
		Class<?> clas = father.class;
	} 
	catch (Exception e) 
	{
		e.printStackTrace();
	}
}

}
无输出

验证5:

public class ClassInit1 {

	public static void main(String[] args) {
		try 
		{		
			Class<?> clas =  Class.forName("father", false, new myloader());
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
}
class myloader extends ClassLoader{
}

无输出

验证6:

public class ClassInit1 {

	public static void main(String[] args) {

		try 
		{
			myloader loader = new myloader();
			Class<?> clas = loader.loadClass("father");
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
}

无输出

什么情况下会引发类的加载

1.遇到new,getstatic,putstatic,invokestatic这四条字节码指令,场景在创建实例,读写类的静态变量,调用类的静态方法时
2.使用java.lang.reflect包中方法对类进行反射调用的时候
3.初始化子类之前初始化父类
4.虚拟机启动时,用户指定执行的主类,虚拟机会先初始化这个类
待补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值