2

私はジェネリック医薬品を 1 時間使用してきましたが、疑問があります。私はこのようなクラスを持っているとしましょう:

class Pair<T>
{
       public T getFirst() { return first; }
}

基本的に私の本はこう言っています:

型消去:型変数は消去され、それらの境界型 (または境界のない変数の場合はオブジェクト) に置き換えられます。

したがって、私の本の声明によると、JVMのコードは次のようになります。

 class Pair
    {
           public Object getFirst() { return first; }
    }

今私がする場合:

   Pair<String> pair = new Pair<>(); //I use Java 7 diamond syntax here.
   pair.getFirst()

戻り値の型をからObjectに変換する必要がありますか?StringgetFirst

今conisder:

ArrayList<String> files = new ArrayList<>();

同じ本は言っています(上記のコードに関しては):

....the files contain array of Strings.

上記の例の型消去規則について、私は非常に混乱していArrayListます。この場合、どうして配列が配列filesを持っていることを知っているのStringでしょうか? (これは型消去規則に矛盾しています)

編集:

の結果のコードPair(つまり、型消去がどのように行われたか) を確認するには、javapここでツールを使用するにはどうすればよいですか?

ここで何か不足していますか?

4

2 に答える 2

4

混乱は、コンパイラーの機能とJVMの機能に起因します。

Pair<String> pair = new Pair<>(); //I use Java 7 diamond syntax here.
String first = pair.getFirst();

JVMではと同等です

Pair pair = new Pair(); 
String first = (String) pair.getFirst();

Map.get()の場合

Map<Key, Value> map = ...
Value value = map.get(key);

JVMにあります

Map map = ...
Value value = (Value) map.get(key);

これもまた、getFirstの戻り型でコードをオブジェクトから文字列に変換する必要がありますか?

変換は行われません。オブジェクトは変更されません。発生するのは、参照のキャストチェックがある可能性があることだけです。

結果のPairのコード(つまり、型消去がどのように行われたか)を確認するために、ここでjavapツールを使用するにはどうすればよいですか?

使用するjavap -c -classpath . ClassUsingPair

于 2012-08-08T11:28:53.937 に答える
0

1. Erasureは、コンパイラがクラスとメソッド、変数などからのコンパイル中にとを削除するプロセスです。 Type parameterType arguments

2. BoxはBoxになります。これはraw-typeと呼ばれます。Raw-typeは、ジェネリッククラスまたはインターフェイス名にtype引数がないものです。

3.したがって、実行時にジェネリックスを見つけることはできません...これは主にジェネリックスを使用しないコードを問題なく実行するために行われ、主にジェネリックスが存在する前に作成されたものです。

4.汎用クラスはインスタンス化されません。コンストラクターを開始する必要があるためです。これは、実行時に元のTypeパラメーターが存在しないため発生しません。

于 2012-08-08T11:26:11.760 に答える