1

クラスファイルの定数プールセクションの下にある次の2つのエントリを見つけようとしています:

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 ドキュメントには何も見つかりませんでした。

ありがとう

4

1 に答える 1

4

定数プールには、「メソッドの開始」と「メソッドの終了」という概念がありません。

ここに実際に表示されているのは、定数プールに「Utf8」型を持つ文字列定数です。プールの観点からは、これらは単なる文字列ですが、さまざまなものを表すコンパイラによって生成された文字列です。これらの文字列は必須であり、その形式は JVMS で説明されています。いくつかの種類があります。あなたのラムダの例から:

  • lambda$new$0- これは、4.3.4で説明されている署名です。
  • (I)I- これは、 4.3.3で説明されているメソッド記述子です(署名とは異なります)。
  • I- これは、 4.3.2で説明されているフィールド記述子です。

単純なIエントリは、 type の単なるフィールドですint

(I) Iエントリの場合、 の間の文字列は(..)パラメータ タイプです。リストにすることができます。Iプリミティブ型intです。の外側の文字列(..)は戻り値の型です。したがって(I) I、 を受け入れるパラメータ リストintと の戻り値の型を持つメソッドを記述しますint

具体的には、JVMS からのメソッド記述子文字列の形式は次のとおりです。

MethodDescriptor:
    ( ParameterDescriptor* ) ReturnDescriptor

ParameterDescriptor:
    FieldType

ReturnDescriptor:
    FieldType
    VoidDescriptor

VoidDescriptor:
    V

FieldTypeの場所(表 4.2から):

文字タイプの解釈
B バイト符号付きバイト
C char Basic の Unicode 文字コード ポイント
                           UTF-16 でエンコードされた多言語面
D double 倍精度浮動小数点値
F float 単精度浮動小数点値
I int 整数
J long long integer
L クラス名; クラス ClassName のインスタンスを参照する
Sショートサインショート
Z boolean true または false
[ 1 つの配列次元を参照

ただし、これらは他の文字列と同様に文字列であることに注意してください。これらのメソッドを実際に呼び出すと、別の種類のエントリ (メソッド参照) が定数プールに表示されます。javapこれらを「NameAndType」タイプで識別し(文字列の「Utf8」とは対照的に)、次のような形式を取ります(最初の例を使用):

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

これらは、メソッド名の文字列と記述子の文字列を参照します。

javapドキュメント自体はかなりまばらで、コマンド ライン情報のみが含まれています。JVMS は、詳細なマニュアルに最も近いものですjavap

于 2014-04-10T14:30:51.343 に答える