1

これらのファイルがある場合:

//Gizmo.java
public class Gizmo {
    public static void main(String[] args) {
        Gadget g = new Gadget();
    }
}

.

//Gadget.java
public class Gadget {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

そして、両方を でコンパイルしてjavac Gizmo.java Gadget.javaから、質問があります。Gizmo.classファイルは「ガジェット」クラスをどのように参照しますか? ファイルのどこかに "Gadget" という文字列だけがありますか?

4

2 に答える 2

1

あなたの答えは、JLS4.2.1の次の行にあります。

クラス ファイル構造に表示されるクラス名とインターフェイス名は、常にバイナリ名 (JLS §13.1) と呼ばれる完全修飾形式で表されます。そのような名前は、常に CONSTANT_Utf8_info 構造体 (§4.4.7) として表されるため、それ以上の制約がなければ、Unicode コード空間全体から引き出すことができます。クラスおよびインターフェース名は、それらの記述子の一部としてそのような名前を持つ CONSTANT_NameAndType_info 構造体 (§4.4.6) (§4.3)、およびすべての CONSTANT_Class_info 構造体 (§4.4.1) から参照されます。

歴史的な理由から、クラス ファイル構造に現れるバイナリ名の構文は、JLS §13.1 に記載されているバイナリ名の構文とは異なります。この内部形式では、通常はバイナリ名を構成する識別子を区切る ASCII ピリオド (.) が ASCII スラッシュ (/) に置き換えられます。識別子自体は非修飾名でなければなりません (§4.2.2)。

于 2013-07-03T19:47:53.797 に答える
1

コメントが述べたように、ここでフォーマットの正確な定義を見つけることができます: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.2

(私の理解では) 長短は、参照されているクラスの名前を示す UTF-8 文字列があり、a) それに関連付けられた任意の番号または b) のいずれかがあると推測しています。その文字列のアドレスが使用されるため、残りのバイナリ クラス ファイルは単にその番号を使用してクラスを参照します。

たとえば、質問のサンプル コードをコンパイルしてGizmo.classからテキスト エディタで開くと、そこに文字列「Gadget」が表示されます。

于 2013-07-03T19:46:43.427 に答える