我试图找出类文件中常量池部分下面的以下两个条目:
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文档上找不到任何内容。
由于
答案 0 :(得分:4)
常量池没有"方法启动"的概念。和"方法结束"。
你在这里看到的是字符串常量,其类型为" Utf8"在恒定的池中。从池的角度来看,这些只是字符串 - 但是,它们是编译器生成的表示各种事物的字符串。这些字符串是必需的,它们的格式在JVMS中描述。有几种类型。从你的lambda例子:
简单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 reference。 javap
使用" NameAndType"标识这些内容。类型(而不是" Utf8"对于字符串),它们将采用类似的形式(使用您的第一个示例):
#123 = NameAndType #11:#12; // "foo":(I)I
它们引用方法名称字符串以及描述符字符串。
javap
文档本身相当稀疏,只包含命令行信息。 JVMS与javap
具有的详细手册最为接近。