类加载时机

类的整个生命周期:
  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载

验证,准备,解析又统称连接。
加载,验证,准备,初始化,卸载这5个阶段总是按顺序“开始”(而不是顺序进行或者完成)

有且只有5种情况必须立即对类进行初始化

  • 遇到new、getstatic、putstatic、invokestatic这4个字节码指令,如果类没有被初始化,则立即初始化。常见场景是new对象,读取静态字段(final修饰的除外,编译器已经加入调用类的常量池),调用一个类的静态方法时。
  • 使用java.lang.reflect包的方法对类进行反射调用时。
  • 当初始化一个类的时候,如果其父类还没有初始化,则先触发其父类初始化。
  • 当虚拟机启动时,虚拟机会先初始化指定包含main()方法的那个类。
  • JDK1.7增加动态语言的支持。如果一个java.lang.invoke.MethodHandle实例最后的解析结果是REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄,而这个句柄所在的类没有进行初始化,则需要先触发初始化。

除了这5个场景,其他引用类的方式都不会触发其初始化。如

  • 子类.父类静态属性(或方法) //会初始化父类,不会初始化子类
  • SomeClass[] sc = new SomeClass[10];//触发一个名为“[L”+SomeClass全类名 的类的初始化阶段。由虚拟机自动生成,字节码指令为newarray
  • 调用static final 修饰的常量

在准备阶段,变量被赋初始值

<client>() 方法是由编译器自动收集类中的所有类变量的赋值动作和static{}块中的语句合并产生的,按源文件代码顺序收集。
static{}块中只能访问定义在其之前的变量,定义在其后的变量可以赋值,但不能访问。

<client>()方法由虚拟机保证其父类的<client>()方法已经执行完毕。
<client>()方法由虚拟机保全其在多线程的情况下被正确的加锁,同步,只有一个线程会去执行初始化操作,其他的线程处于阻塞状态。

public class DeadLoopClass {
static{
    if(true){//没有if的话会initializer must be able to complete normally
        while (true){
                            System.out.println(Thread.currentThread()+"looping");
            }
        }
    }
}
public class TestDeadLoopClass {
public static void main(String[] args) {
        Runnable script1 = new Runnable() {
        @Override
        public void run() {
                            System.out.println(Thread.currentThread()+"start");
                DeadLoopClass dlc = new DeadLoopClass();
                            System.out.println(Thread.currentThread()+"over");
            }
        };
        Thread t1 = new Thread(script1);
        Thread t2 = new Thread(script1);
        t1.start();
        t2.start();
    }
}

Thread[Thread-1,5,main]start
Thread[Thread-0,5,main]start
Thread[Thread-1,5,main]looping
Thread[Thread-1,5,main]looping
Thread[Thread-1,5,main]looping

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值