诚如foxty(狐狸糊涂) 所说,书中解释也是说Strange1在连接阶段的校验产生异常 按他的解释要分析下字节码,比如我用 javap -c Strange1看字节码: public class Strange1 extends java.lang.Object{ public Strange1(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return
public static void main(java.lang.String[]); Code: 0: new #2; //class Missing 3: dup 4: invokespecial #3; //Method Missing."<init>":()V 7: astore_1 8: goto 20 11: astore_1 12: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 15: ldc #6; //String Got it! 17: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;>V ing;)V 20: return Exception table: from to target type 0 8 11 Class java/lang/NoClassDefFoundError
} 按照他的解释如下: 由于指令20(return)可以通过两种路径到达,因此效验器必须合并变量1中的类型(astore_1),两种类型通过计算他们的首个公共超类(first common superclass)而合并的,两个类的首个公共超类是它们所共有的最详细而精确的类. 在Strange1.main方法中,当从指令8到达指令20时,VM变量1的状态包含了一个Missing类的实例.,当从指令17到达20时,它包含了一个NoClassDefFoundError类的实例.为了计算首个公共超类,效验器必须加载Missing类以确定其超类.因为Missing.class被删除了,所以不能加载它,因而抛出NoClassDefFoundError异常.此异常在效验期间,初始化之前被抛出.
复述了一遍,我大概理解了为何Strange1抛出异常,那么,对于Strange2我是否可以这样理解,因为变量1首先是个Null实例,后来再有个NoClassDefFoundError类的实例,两者的首个公共超类都为Object,在此过程中(效验过程)并不需要加载Missing类,只有在初始化时才加载.我的理解正确不?谢谢
|