2013-04-09 26 views
7

私は、javaのジェネリックスでタイプ消去についてHerbert Schildsを読んでいます。おそらくクラスでjavapを実行すると、タイプ消去後のパブリック、パッケージ保護、保護されたフィールドとメソッドに関するバイトコード情報が得られます。しかし、私は次のクラスを書いた:javapとジェネリックスのタイプ消去

class Ambiguity<T, V extends String>{ 
    T ob1; 
    V ob2; 

    void set(T o){ 
     ob1 = o; 
    } 

    void set(V o){ 
     ob2 = o; 
    } 
} 

をして生成されたクラスファイルに走ってjavapと私がいた「Test.java」

class Ambiguity<T, V extends java.lang.String> { 
    T ob1; 
    V ob2; 
    Ambiguity(); 
    void set(T); 
    void set(V); 
} 

からコンパイルされた次の出力

を得ました私が読んだものに基づいてこのように見える出力を期待しています。

Compiled from "Test.java" 
class Ambiguity<java.lang.Object, java.lang.String> { 
    java.lang.Object ob1; 
    java.lang.String ob2; 
    Ambiguity(); 
    void set(java.lang.Object); 
    void set(java.lang.String); 
} 

ここに何か不足していますか?私は、上記の方法でメソッドをオーバーロードするのは良い方法ではないことを理解しています。私はちょうどこのあいまいさの下でjavapの結果を見るのに興味があることを見ていた。

編集:これはjavapの新しい修正の結果であるようです。 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4870651

JDK 1.6からjavapを実行すると、期待通りの結果が得られます。私が最初に使用していたJDK 1.7 b30からjavapを実行すると、汎用情報が得られます。

答えて

3

コンパイル時 - 生成されたバイトコード - クラスでは、すべてのジェネリック型情報が保持されます。あなたが見たことはまさにあなたが期待すべきものです。

違いは、種類がランタイムに消去されていることである:例えば、クラスAmbiguity<Integer, String>インスタンスは、その型の引数は、それぞれIntegerStringであることを知ることができません。

+0

お返事ありがとうございます。 Schilds氏は次のように述べています。「Javaコードがコンパイルされると、すべてのジェネリック・タイプ情報が削除(消去)されます。彼は上の最後のようにjavapを実行した結果を示します。 –

+0

それからSchildsは間違っています。型消去はランタイム現象であり、クラスがジェネリック型情報を保持しているという事実を利用する多くのユーティリティがあります。そのメタデータを失うのは単に_instances_なのです。 –

+0

SOに関する別の質問も同じことを言っています:http://stackoverflow.com/questions/11966091/displaying-generic-type-parameters-from-compiled-class-files –