gpt4 book ai didi

描述符和签名属性之间的Java内部类不一致? (类文件)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:56:02 24 4
gpt4 key购买 nike

我正在尝试了解规范中是否存在内部类的 Java 描述符和签名之间存在差异的原因。 (我这里是直接看类文件的内容,但是我用javap来说明)。

( n.b. 我已经在 J​​DK 1.6.0_33 和 1.7.0_05 上尝试过,使用 Java 7 的 javap 查看时 - java 6 的 javap 似乎没有显示任何通用的问题签名信息,根据下面肖恩的回答。)

更新:感谢那些讨论 - 我的看法是

  • 描述符(不包含一般信息)是正确的。
  • 签名(它是方法的一个属性,确实包含通用信息)不正确。 方法的 SIGNATURE 的相关 ConstPool 条目是“ConstantUTF8[(Ljava/util/list )V] ”
  • 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

鉴于肖恩在下面的回答,我尝试在 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com