我试图了解规范中是否有理由说明内部类的Java描述符和签名之间的差异。 (我在这里直接查看类文件的内容,但是我使用javap进行说明)。
(n.b.我已经在JDK 1.6.0_33和1.7.0_05上进行了尝试,当使用来自Java 7的javap进行查看时,它们都有相同的问题-根据下面的Sean的回答,java 6的javap似乎没有显示任何通用签名信息。
更新:感谢那些讨论-我的看法是
万一有人怀疑,我没有使用JAVAP就打了这个,只是我自己看了类文件,我只是用javap来显示它。 (因此不太可能是javap错误)。
考虑:
public class InnerClassTest1 {
public int getX() {
return new Inner1(new ArrayList<String>()).getX(4);
}
public class Inner1 {
private final List arg;
public Inner1(List arg) {
this.arg = arg;
}....
与
public class InnerClassTest2 {
public int getX() {
return new Inner1(new ArrayList<String>()).getX(4);
}
public class Inner1<E> {
private final List<E> arg;
public Inner1(List<E> arg) {
this.arg = arg;
}.....
如果您查看内部类上javap -cs的输出,它们的区别令人惊讶!
公共(public)org.benf.cfr.tests.InnerClassTest1 $ Inner1( org.benf.cfr.tests.InnerClassTest1, java.util.List);
签名:(Lorg/benf/cfr/tests/InnerClassTest1; Ljava/util/List;)V
与
公共(public)org.benf.cfr.tests.InnerClassTest2 $ Inner1(java.util.List );
签名:(Lorg/benf/cfr/tests/InnerClassTest2; Ljava/util/List;)V
...使用泛型的那个缺少外部类的隐式参数! (在InnerClassTest1中正确存在)。
我在类文件文档中找不到任何可以解释的内容-有人知道为什么会这样吗?
谢谢!
李
更新 -
我已将示例文件放置在http://www.benf.org/files/innerClassTest.tgz上
给定下面的Sean答案,我尝试在java 6上使用javap,并且看到两者的输出相同,没有通用信息-这使我相信Java 6的javap不会显示完整的签名信息?
我在1.7.0_05-b06上使用javap获得的确切输出是
public class org.benf.cfr.tests.InnerClassTest2$Inner1<E> {
final org.benf.cfr.tests.InnerClassTest2 this$0;
Signature: Lorg/benf/cfr/tests/InnerClassTest2;
public org.benf.cfr.tests.InnerClassTest2$Inner1(java.util.List<E>);
Signature: (Lorg/benf/cfr/tests/InnerClassTest2;Ljava/util/List;)V
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Lorg/benf/cfr/tests/InnerClassTest2;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: aload_0
10: aload_2
11: putfield #3 // Field arg:Ljava/util/List;
14: return
public int getX(int);
Signature: (I)I
Code:
0: iconst_2
1: ireturn
}
最佳答案
使用上面的代码并使用JDK 1.6.0_33,我得到以下输出:
src\test>javap -c -s InnerClassTest1$Inner1
Compiled from "InnerClassTest1.java"
public class test.InnerClassTest1$Inner1 extends java.lang.Object{
final test.InnerClassTest1 this$0;
Signature: Ltest/InnerClassTest1;
public test.InnerClassTest1$Inner1(test.InnerClassTest1, java.util.List);
Signature: (Ltest/InnerClassTest1;Ljava/util/List;)V
Code:
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:Ltest/InnerClassTest1;
5: aload_0
6: invokespecial #2; //Method java/lang/Object."<init>":()V
9: aload_0
10: aload_2
11: putfield #3; //Field arg:Ljava/util/List;
14: return
public int getX(int);
Signature: (I)I
Code:
0: iload_1
1: ireturn
}
src\test>javap -c -s InnerClassTest2$Inner1
Compiled from "InnerClassTest2.java"
public class test.InnerClassTest2$Inner1 extends java.lang.Object{
final test.InnerClassTest2 this$0;
Signature: Ltest/InnerClassTest2;
public test.InnerClassTest2$Inner1(test.InnerClassTest2, java.util.List);
Signature: (Ltest/InnerClassTest2;Ljava/util/List;)V
Code:
0: aload_0
1: aload_1
2: putfield #1; //Field this$0:Ltest/InnerClassTest2;
5: aload_0
6: invokespecial #2; //Method java/lang/Object."<init>":()V
9: aload_0
10: aload_2
11: putfield #3; //Field arg:Ljava/util/List;
14: return
public int getX(int);
Signature: (I)I
Code:
0: iload_1
1: ireturn
}
唯一的区别是我的实现(使代码可以编译):
public int getX(int i) {
return i;
}
以及您的软件包名称可能不同的事实(org.benf.cfr.tests?)。
除此之外,我的输出几乎相同。代码中是否还有其他差异可以解释您所看到的内容?从我对编译过程和类文件的了解中,我不希望看到输出有所不同。
好问题-找出原因的原因很有趣
关于Java内部类描述符和签名属性之间不一致? (类文件),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15131040/