类文件常量池(javap)中的方法签名和描述符

时间:2014-04-10 14:26:55

标签: java .class-file javap

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

int foo(int x) {
    return x;
}

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

条目(1) - > (I)我表示功能的开始和 条目(2) - >我表示功能结束。

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

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文档上找不到任何内容。

由于

1 个答案:

答案 0 :(得分:4)

常量池没有"方法启动"的概念。和"方法结束"。

你在这里看到的是字符串常量,其类型为" Utf8"在恒定的池中。从池的角度来看,这些只是字符串 - 但是,它们是编译器生成的表示各种事物的字符串。这些字符串是必需的,它们的格式在JVMS中描述。有几种类型。从你的lambda例子:

  • lambda$new$0 - 这是签名,在4.3.4中有描述。
  • (I)I - 这是一个方法描述符(与签名不同),在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):

Character     Type       Interpretation
B             byte       signed byte
C             char       Unicode character code point in the Basic 
                           Multilingual Plane, encoded with UTF-16
D             double     double-precision floating-point value
F             float      single-precision floating-point value
I             int        integer
J             long       long integer
L ClassName;  reference  an instance of class ClassName
S             short      signed short
Z             boolean    true or false
[             reference  one array dimension

但请注意,这些仍然是其他任何字符串。当您实际调用这些方法时,会在常量池中显示不同类型的条目 - method referencejavap使用" NameAndType"标识这些内容。类型(而不是" Utf8"对于字符串),它们将采用类似的形式(使用您的第一个示例):

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

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

javap文档本身相当稀疏,只包含命令行信息。 JVMS与javap具有的详细手册最为接近。

相关问题