我一直在用Java字节码进行一些个人研究,但我发现有点奇怪。如果我反编译this class,我会在常量池中找到对Class.forName()
的引用。但是,源代码中没有引用此方法。
我假设有关此代码的一些事情导致javac发出一些动态加载类的代码,但我不确定为什么会这样。它让我觉得效率低下,但主要是我只是好奇为什么会发生这种情况。
答案 0 :(得分:2)
在用javap
反汇编代码之后,我注意到源代码中不存在一种方法:
static java.lang.Class class$(java.lang.String);
Code:
0: aload_0
1: invokestatic #1 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
4: areturn
5: astore_1
6: new #3 // class java/lang/NoClassDefFoundError
9: dup
10: invokespecial #4 // Method java/lang/NoClassDefFoundError."<init>":()V
13: aload_1
14: invokevirtual #5 // Method java/lang/NoClassDefFoundError.initCause:(Ljava/lang/Throwable;)Ljava/lang/Throwable;
17: athrow
Exception table:
from to target type
0 4 5 Class java/lang/ClassNotFoundException
看起来这是在为版本&lt;编译的字节码中生成的。只要代码 [1]中引用了类文字,就会出现JDK1.5。基本上,这个:
if (getClass() == Level.class) {}
变成了这个:
if (getClass() == class$("org.apache.log4j.Level")) {}
和class$()
看起来像这样:
static Class class$(java.lang.String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError();
}
}
显然在JDK1.5中,ldc_w
指令被赋予了加载类常量的能力,并且不再需要class$()
方法。