6

オラクルのウェブサイトで次の質問と回答を見つけました

型消去後に変換された次のクラスは何ですか?

public class Pair<K, V> {

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey(); { return key; }
    public V getValue(); { return value; }

    public void setKey(K key)     { this.key = key; }
    public void setValue(V value) { this.value = value; }

    private K key;
    private V value;
}

答え:

public class Pair {

    public Pair(Object key, Object value) {
        this.key = key;
        this.value = value;
    }

    public Object getKey()   { return key; }
    public Object getValue() { return value; }

    public void setKey(Object key)     { this.key = key; }
    public void setValue(Object value) { this.value = value; }

    private Object key;
    private Object value;
}

しかし、JD-GUI を使用してクラス ファイルを逆コンパイルすると、実際のソース コードにあるものと同様のジェネリック型がすべて表示されます。

これは、ジェネリック型がクラス ファイルに保持されているということですか? 私はJava 6を使用しています。

JD-GUIを使用したクラスの逆コンパイラ版は以下の通りです。クラスのコンパイルには Eclipse Helios を使用しています。

public class Pair<K, V>
{
  private K key;
  private V value;

  public Pair(K key, V value)
  {
    this.key = key;
    this.value = value;
  }
  public K getKey() {
    return this.key; } 
  public V getValue() { return this.value; } 
  public void setKey(K key) {
    this.key = key; } 
  public void setValue(V value) { this.value = value;
  }
}
4

1 に答える 1

7

一部のジェネリック型情報は .class ファイルに保持されます。リフレクションによって、Pair 型がジェネリックであることや、Pair メンバーを持つクラスのジェネリック パラメーターの型などを判断するのに十分です。この情報が保持されるという事実は、ジェネリック パラメーターに関する情報を保持する型トークンを渡すことができるスーパー型トークンのような手法の基礎を形成します。

ただし、リフレクション以外では、型の消去は、Pairクラスがほとんどの場合、Oracle Web サイトの「回答」の削除されたバージョンのように動作することを意味します。特に、メソッドの実際のバイトコードは、ジェネリック型KまたはVオブジェクトのみへの参照を持たず、メソッド シグネチャは を受け入れて返しObjectます。

この場合、JD-GUI は賢く、.class ファイルに格納された情報を使用して、逆コンパイルされた出力の一般的な情報を復元しますが、型がバイトコードで消去されていることを確認してください。

于 2012-12-29T00:51:56.793 に答える