0

コンパイルされたクラスのどのセクションに、他のクラスへの依存関係 (インポート) が格納されており、それらを (エディターまたはプログラムではないもので) 表示できますか?

ありがとう、

4

1 に答える 1

2

これは、クラスの「定数プール」に格納されます (他のすべてのもの、クラス、メソッド名などとともに)。

読み取り可能な形式でバイトコードを調べるには、javap を使用します。

バイトコードの基礎に関する Anton Arhipov の優れたブログを参照してください。

そこから取られたクラスの例:

public class Foo {
    private String bar;

    public String getBar(){ 
      return bar; 
    }
    ...

... バイトコードが生成されます:

public java.lang.String getBar();
  Code:
   0:   aload_0
   1:   getfield        #2; //Field bar:Ljava/lang/String;
   4:   areturn

そして一定のプールがあります:

Compiled from "Foo.java"
public class Foo extends java.lang.Object
  SourceFile: "Foo.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #4.#17; //  java/lang/Object."<init>":()V
const #2 = Field        #3.#18; //  Foo.bar:Ljava/lang/String;
const #3 = class        #19;    //  Foo
const #4 = class        #20;    //  java/lang/Object
const #5 = Asciz        bar;
const #6 = Asciz        Ljava/lang/String;;
const #7 = Asciz        <init>
const #8 = Asciz        ()V;
const #9 = Asciz        Code;
const #10 = Asciz       LineNumberTable;
const #11 = Asciz       getBar;
const #12 = Asciz       ()Ljava/lang/String;;
const #13 = Asciz       setBar;
const #14 = Asciz       (Ljava/lang/String;)V;
const #15 = Asciz       SourceFile;
const #16 = Asciz       Foo.java;
const #17 = NameAndType #7:#8;//  "<init>":()V
const #18 = NameAndType #5:#6;//  bar:Ljava/lang/String;
const #19 = Asciz       Foo;
const #20 = Asciz       java/lang/Object;

次のように、定数プールを介してStringfromへの参照をトレースできます。Foo#getBar

  • ゲットフィールド #2
  • #2 はフィールドで、#3 を参照しています。#18
    • #3はクラス#19を参照しています
      • クラスですFoo
    • #18 は #5 と #6 を参照する NameAndType です。
      • #5はバー(フィールド)です
      • #6はへの参照ですjava.lang.String

アントンのブログを読むことを強くお勧めします。本当によくできています!

また、 James D. Bloom の JVM Internals の記事も読んでみたいと思います。JVM の内部アーキテクチャがたくさん取り上げられているからです。ただし、物事が変化するにつれて参照される日付とバージョンに注意してください (Java 8 での Java ヒープの使用や文字列のインライン化など)。

于 2013-11-07T12:16:24.330 に答える