类加载机制分析并附代码解析(上)

目录


代码与结果

public class ClassloadOrder {
	public static void main(String[] args) {
		staticFuncton();
	}

	static ClassloadOrder st0 = new ClassloadOrder();

	static {
		System.out.println("1");
	}
	{
		System.out.println("2");
	}

	ClassloadOrder() {
		System.out.println("3");
		System.out.println("a=" + a + "," + "b=" + b);
	}
	
	private static void staticFuncton() {
		System.out.println("4");

	}

	int a = 110;
	
	static int b = 112;

}

论坛的人很多是这样回答的:1234 可能他们认为因为静态构造肯定是要比动态构造快的。这也的确是对的。

按照JAVA中赋值顺序
1.父类的静态变量赋值
2.自身的静态变量赋值
3.父类成员变量赋值
4.父类块赋值
5.父类构造器赋值
6.自身成员变量赋值
7.自身块赋值
8.自身构造器赋值

但是输出却很“惊人”(特地贴一张运行结果图)

按照惯例还是开始一顿学习。

类加载的生命周期

     (1) 装载:查找和导入Class文件;(把内容加载到内存并形成class结构)

     (2) 链接:把类的二进制数据合并到JRE中;(java为了增强语言动态性,把link过程转移到了运行时期)

        (a)校验:检查载入Class文件数据的正确性;(如确认无误,可使用 Xverify:none 命令跳过该过程)

        (b)准备:给类的静态变量分配存储空间,(同时给基本变量分配空间,如果有初始值并赋值,没有则赋默认值);

        (c)解析:将符号引用转成直接引用;(把通用语言翻译成这台机器的可执行内容,就像是偏移地址变成直接地址)

     (3) 初始化:对类的静态变量,静态代码块执行初始化操作(把需要执行static内容顺序整合成<clinit>类构造器方法执行)

     (4)使用

     (5)卸载

     PS:()内内容为我本人添加,() 以外内容引用自 深入理解Java:类加载机制及反射 - ^_TONY_^ - 博客园

类加载的触发条件

 主动引用(触发):

    (1) 使用 new、getstatic、putstatic、invokestatic这四条字节码指令,(后面三条均是对类的static部分操作,前两个对应域,最后的对应方法。)

    (2) 使用 java.lang.reflect 包的方法对类进行反射调用的时候

    (3) 当派生类需要进行初始化时,先初始化基类

    (4) 当虚拟机启动时,自动加载的主类(多数情况是包含main()的那个类)

   (5) 当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle 实例最后解析的结果为 REF_getStatic、REF_putStatic、REF_invokeStatic 的方法句柄。(这个暂时没使用过,就理解为加强版的 Method方法和C++里面句柄的结合体)

    以上共有特性:当然是类没有加载过了。

  被动引用(不触发):

    (1) 通过派生类使用基类的Static内容。(根据RTTI思想,本来就没调用的是派生类的内容,当然不加载)

    (2) 使用数组申明的语法。例:NotInitialization[]  not =new NotInitialization[10]  。

    (3) 使用被final修饰的常量。(已经在常量池之中)

     更详细内容可参阅 类加载的过程 - fengbs - 博客园 或者 《深入理解java虚拟机》 P209-227

详细分析:

     首先jvm启动,首先加载 main()方法所在的ClassLoadOrder类。

     (1) 装载过程:成功加载ClassLoadOrder类

     (2) 链接:略。

        (a)校验:略。

        (b)准备:给a在常量池申明内存并赋值,给b申明内存赋默认值

        (c)解析:略。

     (3) 初始化:按照顺序st0申明内存到堆中,并且开始执行new指令。发现ClassLoadOrder已在加载,不再次加载,执行构造代码块,输出2,执行构造函数输出3 和a=110,b=0(因为b还没被赋值);     执行下一条static语句,就是static代码块输出1,b被赋值为112。

     (4)使用:调用static方法,输出4

     (5)卸载:略。

由此,完整输出以上图片的内容。2314.

如需查看类加载器相关知识可查阅下篇:类加载机制分析并附代码解析(下)_想当架构师的码农-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值