2017-05-27 15 views
0

セイ.. Javaコンパイラは、すべてのタイプの情報を消去し、(前述場合)は、その上限を持つものの出現をすべて置き換えるか、オブジェクト...Javaのジェネリック - 抹消メカニズム

私の質問はありません:キャストのない挿入ここで行われます。キャストは後で、このタイプのinfo-freeクラスに対して他のクラスがコンパイルされたときに発生します。ここでは、他のクラスの補足型引数に応じて、汎用クラスが再コンパイルされ(2回目)、すべてのキャストが配置されますクラスは実行時間の準備ができています..そうですか?

答えて

4

いいえ、クラスは再コンパイルされません。キャストは、コンクリートタイプとジェネリックタイプの境界で行われます。

これを理解しようとしている場合は、ジェネリッククラスを生のタイプとして使用することができます(ジェネリックスを使用しない)。具体的なタイプは(この場合String)が知られている場合にキャストを挿入する

List l = new ArrayList(); // An `ArrayList<String>` before generics. 

l.add("Hello"); 
String s = (String) l.get(0); 

:インスタンスArrayListため。それらは、クラスの中に挿入されたではなく、であり、本当にその必要はありません。

+0

ありがとう。したがって、キャストは実際にはジェネリッククラスではなくユーザークラス内にあります。また、上記の例を参照して、リストを指定した場合、明示的に挿入されたStringへのキャストはJavaコンパイラによって自動的に挿入されます。 – Searcherer

+2

@Searchererはい、キャストはユーザーのクラスにあります。 'ArrayList'の型パラメータの消去は' Object'ですが、あなたがより具体的な型を必要とするユーザクラスでのみ、それがキャストする場所です。そして、そうです、そのキャストは 'ArrayList 'の場合に自動的に挿入されます。 'add'メソッドのキャストはないことに注意してください。 –

+0

ありがとうございました。最後の小さなことを聞​​きたいだけです。addメソッドのキャストがないことに注意して、コンパイラは引き続きaddのシグネチャに対して与えられた引数を入力します。これは型パラメータに基づいて異なる可能性があります。 。右? – Searcherer

0

鋳造他のいくつかのクラスがこの 型情報のないクラスに対してコンパイルされたときにはありません、キャストがクラス自体のコンパイルフェーズ中に実行される

、後に発生します。
コンパイルされたクラスは、依存するクラスに応じて変更すべきではありません。この方法で

ルック:

public void doSomething(); 
    Code: 
     0: new   #15     // class java/util/ArrayList 
     3: dup 
     4: invokespecial #17     // Method java/util/ArrayList."<init>":()V 
     7: astore_1 
     8: aload_1 
     9: iconst_1 
    10: invokestatic #18     // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 
    13: invokeinterface #24, 2   // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 
    18: pop 
    19: aload_1 
    20: iconst_0 
    21: invokeinterface #30, 2   // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 
    26: checkcast  #19     // class java/lang/Integer 
    29: astore_2 
    30: return 

キャストが実際にコンパイラによって追加された:ここで

public class TestCast { 

    public void doSomething(){ 
     List<Integer> values = new ArrayList<>(); 
     values.add(1); 
     Integer value = values.get(0); 
    } 
} 

は(javapツールを使用して行われる)TestCastコンパイルされたクラスの解体方法であります:

26: checkcast  #19     // class java/lang/Integer 
0

何もない今まで述べてきた答えは橋の方法です。

public class GenericTest implements Comparable<GenericTest>{ 

    @Override 
    public int compareTo(GenericTest o) { 
     return 0; 
    } 
} 

コンパイラは、実際には2つの方法を作成します。 int compareTo(Object);は、キャストして転送する予定であり、期待されている。int compareTo(GenericTest)

関連する問題