分析Java类加载全过程
作者:网络转载 发布时间:[ 2012/11/8 10:25:54 ] 推荐标签:
首先Sub.B中对静态数据进行了引用,Sub类要进行初始化了。同时,其父类Parent要先进行初始化动作。Parent初始化后,A=2,所以B=2;上个过程相当于:
static class Parent{
<clinit>(){
public static int A=1;
static{
A=2;
}
}
}
static class Sub extends Parent{
<clinit>(){ //jvm会先让父类的该方法执行完在执行这里
public static int B=A;
}
}
public static void main(String[] args){
System.out.println(Sub.B);
}
<clinit>();方法对类跟接口来说不是必须的,加入类或者接口中没有对类变量进行赋值且没有静态代码块,<clinit>()方法不会被编译器生成。
由于接口里面不能存在static{}这种静态代码块,但仍然可能存在变量初始化时的变量赋值操作,所以接口里面也会生成<clinit>()构造器。但跟类的不同的是,执行子接口的<clinit>();方法前并不需要执行父接口的<clinit>();方法,当父接口中定义的变量被使用时,父接口才会被初始化。
另外,接口的实现类在初始化的时候也一样不会执行接口的<clinit>();方法。
另外,jvm会保证一个类的<clinit>();方法在多线程环境下能被正确地加锁同步。<因为初始化只会被执行一次>。
下面用个例子说明一下:
public class DeadLoopClass {
static{
if(true){
System.out.println("要被 ["+Thread.currentThread()+"] 初始化了,下面来一个无限循环");
while(treu){}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("toplaile");
Runnable run=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("["+Thread.currentThread()+"] 要去实例化那个类了");
DeadLoopClass d=new DeadLoopClass();
System.out.println("["+Thread.currentThread()+"] 完成了那个类的初始化工作");
}};
new Thread(run).start();
new Thread(run).start();
}
}
这里面,运行的时候将会看到阻塞现象。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11