我一直在做一些關於Java字節碼的個人研究,並且遇到了一些奇怪之處。如果我反編譯this class,我發現參考Class.forName()
掛在常量池中。但是,源代碼中沒有提及此方法。爲什麼Class.forName出現在這個類的字節碼中?
我認爲這段代碼會導致javac發出一些動態加載類的代碼,但我不知道爲什麼會發生這種情況。它讓我覺得效率低下,但主要是我很好奇爲什麼會發生這種情況。
我一直在做一些關於Java字節碼的個人研究,並且遇到了一些奇怪之處。如果我反編譯this class,我發現參考Class.forName()
掛在常量池中。但是,源代碼中沒有提及此方法。爲什麼Class.forName出現在這個類的字節碼中?
我認爲這段代碼會導致javac發出一些動態加載類的代碼,但我不知道爲什麼會發生這種情況。它讓我覺得效率低下,但主要是我很好奇爲什麼會發生這種情況。
與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
它看起來像這樣的字節碼生成編譯版本< JDK1.5每當在代碼 [1]中引用類別字面量時。基本上,這個:
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$()
方法不再需要。
爲什麼不發佈該類,以及反編譯的結果,其中包含令人驚訝的Class.forName()。這會阻止我們猜測。 –
忘記勾選「回答您的問題」框時,我做到了這一點。我寫了這個問題,我想到javap可能會指出它爲什麼會發生。想象我會把它發佈給任何碰到它的人。 – monitorjbl
2016年12月25日,當Java 1.4 [2008年10月30日終止](http://www.oracle.com/)時,您正在回答*** Java 1.4 ***問題technetwork/java/javase/index-jsp-138567.html),超過8年前?你是否渴望[自學者]徽章?(http://stackoverflow.com/help/badges/14/self-learner)徽章?這個問題/答案已經過時了,所以我必須同時使用*「無用」*。 – Andreas