【问题标题】:Method signatures and descriptors in class file constant pool (javap)类文件常量池(javap)中的方法签名和描述符
【发布时间】:2014-04-10 14:26:55
【问题描述】:

我试图找出类文件中常量池部分下的以下两个条目:

int foo(int x) {
    return x;
}

#11 = Utf8               foo
#12 = Utf8               (I)I        // 1   
#13 = Utf8               x
#14 = Utf8               I           // 2

条目 (1) -> (I)I 是否表示函数的开始和 条目 (2) -> I 表示函数结束。

此编译器是特定的还是可能因一个编译器而异?

对于 Lambda 函数也有类似的问题。

interface I { int foo(int x); }
class X {
I x = (int x1) -> 0;
}

 #15 = Utf8            lambda$new$0
 #16 = Utf8            (I)I
 #17 = Utf8            x1
 #18 = Utf8            I

抱歉,在 JLS 文档中找不到任何内容。

谢谢

【问题讨论】:

    标签: java .class-file javap


    【解决方案1】:

    常量池没有“方法开始”和“方法结束”的概念。

    您在这里实际看到的是字符串常量,它在常量池中具有“Utf8”类型。从池的角度来看,这些只是字符串——但是,它们是编译器生成的字符串,表示各种事物。这些字符串是必需的,它们的格式在 JVMS 中进行了描述。有几种类型。从您的 lambda 示例中:

    • lambda$new$0 - 这是一个签名,在4.3.4 中描述。
    • (I)I - 这是一个方法descriptor(与签名不同),在4.3.3 中描述
    • I - 这是一个字段描述符,在4.3.2 中描述。

    简单的I 条目只是int 类型的字段。

    对于您的(I) I 条目,(..) 之间的字符串是参数类型。它可以是一个列表。 I 是基本类型 int(..) 之外的字符串是返回类型。所以(I) I 描述了一个方法,其参数列表接受int,返回类型为int

    具体来说,从 JVMS 来看,方法描述符字符串的格式如下:

    MethodDescriptor:
        ( ParameterDescriptor* ) ReturnDescriptor
    
    ParameterDescriptor:
        FieldType
    
    ReturnDescriptor:
        FieldType
        VoidDescriptor
    
    VoidDescriptor:
        V
    

    FieldType 在哪里(来自table 4.2):

    字符类型解释 B 字节 有符号字节 Basic 中的 C char Unicode 字符代码点 多语言平面,用 UTF-16 编码 D double 双精度浮点值 F float 单精度浮点值 我 int 整数 J long long 整数 L 类名;引用类 ClassName 的实例 S 短 有符号短 Z 布尔值 true 或 false [引用一维数组

    但是,请注意,这些仍然是与其他字符串一样的字符串。当您真正调用这些方法时,常量池中将出现一种不同类型的条目 - method referencejavap 将这些标识为“NameAndType”类型(而不是字符串的“Utf8”),它们将采用如下形式(使用您的第一个示例):

    #123 = NameAndType      #11:#12;   // "foo":(I)I
    

    它们引用方法名称字符串以及描述符字符串。

    javap 文档本身相当稀疏,仅包含命令行信息。 JVMS 是最接近 javap 的详细手册的东西。

    【讨论】:

    • 很尴尬。我应该虽然我是int。谢谢。
    • @JasonC 当我回到电脑前,我必须检查它的确切含义,但这就是它所描述的。
    • @Jason 实际上他是对的。这些是该方法引用的常量池条目。这不是调试信息 - 每个方法都必须有一个名称和描述符。
    • @Jason 我已经 wiki 了。能否请您添加我目前无法添加的详细信息?
    猜你喜欢
    • 1970-01-01
    • 2017-10-10
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2013-01-12
    • 2014-04-25
    • 2021-10-27
    相关资源
    最近更新 更多