类的唯一性: 类加载实例 + 类的全名
详情请访问类加载 - 类初始化
// JVM参数:-verbose:class public class Singleton { private Singleton() { } private static class LazyHolder { static final Singleton INSTANCE = new Singleton(); static { System.out.println("LazyHolder.<clinit>"); } } private static Object getInstance(boolean flag) { if (flag) { // Loaded xxx.Singleton$LazyHolder from file:XXX // 新建数组知会导致加载,但不会导致初始化 return new LazyHolder[2]; } // LazyHolder.<clinit> // getstatic指令触发类的初始化 return LazyHolder.INSTANCE; } public static void main(String[] args) { getInstance(true); System.out.println("----"); getInstance(false); } }
新建数组 只会触发加载阶段 ,而 不会触发链接和初始化阶段
$ java -cp ./asmtools.jar org.openjdk.asmtools.jdis.Main Singleton/$LazyHolder.class > Singleton/$LazyHolder.jasm.bak # 将字节码修改为不符合JVM规范,在类加载-链接阶段会报错(从而验证有没有执行到链接阶段) $ awk 'NR==1,/stack 1/{sub(/stack 1/, "stack 0")} 1' Singleton/$LazyHolder.jasm.bak > Singleton/$LazyHolder.jasm $ java -cp ./asmtools.jar org.openjdk.asmtools.jasm.Main Singleton/$LazyHolder.jasm $ java -verbose:class Singleton [Loaded Singleton$LazyHolder from file:/Users/zhongmingmao/Downloads/asmtools-7.0-build/dist/asmtools-7.0/lib/] ---- [Loaded java.lang.VerifyError from /Users/zhongmingmao/.sdkman/candidates/java/8.0.181-oracle/jre/lib/rt.jar] Exception in thread "main" [Loaded java.lang.Throwable$PrintStreamOrWriter from /Users/zhongmingmao/.sdkman/candidates/java/8.0.181-oracle/jre/lib/rt.jar] [Loaded java.lang.Throwable$WrappedPrintStream from /Users/zhongmingmao/.sdkman/candidates/java/8.0.181-oracle/jre/lib/rt.jar] [Loaded java.util.IdentityHashMap from /Users/zhongmingmao/.sdkman/candidates/java/8.0.181-oracle/jre/lib/rt.jar] [Loaded java.util.IdentityHashMap$KeySet from /Users/zhongmingmao/.sdkman/candidates/java/8.0.181-oracle/jre/lib/rt.jar] java.lang.VerifyError: Operand stack overflow Exception Details: Location: Singleton$LazyHolder.<init>()V @0: aload_0 Reason: Exceeded max stack size. Current Frame: bci: @0 flags: { flagThisUninit } locals: { uninitializedThis } stack: { } Bytecode: 0x0000000: 2ab7 0007 b1 at Singleton.getInstance(Singleton.java:22) at Singleton.main(Singleton.java:28)
转载请注明出处:http://zhongmingmao.me/2018/12/16/jvm-basic-load-class-md/
访问原文「类加载」获取最佳阅读体验并参与讨论