0

1) extends が受け入れられているのに、ジェネリックメソッドとクラスが super キーワードを使用しないのはなぜですか?

2)型消去のため、ジェネリックで演算子のインスタンスを使用できませんが、なぜ型キャストが許可されるのですか?

例えば:

 if (objecta instanceof Object){} //doesn't work  
 Collection collection = new ArrayList();   
 Collection<Integer> d1 = (Collection<Integer>)collection; //works fine.  

私の理解では、それを Collection にキャストしようとしていて、実行時に Collection として何もないため、そうすべきではありません。

3)静的変数はジェネリッククラスのメンバーになれないことを読みましたが、その理由はよくわかりません。では、なぜ次の動作が示されるのでしょうか。

 public class NoGenericss  
 { static List<Integer> list; //WORKS FINE  
 static List<T> list1; //COMPILATION ERROR   
 public class Genericss<T>  

 { static List<Integer> list; //WORKS FINE   
 static List<T> list1; //COMPILATION ERROR  
 static void meth(T t){} //COMPILATION ERROR  
 static <S> void meth(S t){} //WORKS FINE

なぜこのような変化する行動が示されるのでしょうか?

4

1 に答える 1

1

Java ジェネリックのリファレンスについては、Sun のチュートリアルを参照してください。

2)

このinstanceof演算子は動的です。つまり、実行時にオブジェクトの型をチェックします。タイプ eraserのため、オブジェクトのジェネリック タイプ (コレクションなど) は実行時に使用できません (a List<Integer>List<String> はList<URI>すべて、一部のオブジェクトの単なるLists になります)。

ただし、キャストは静的です。変数の型パラメーターは、Java コンパイラーによってチェックされます。これを行う場合:

List<Integer> ints = Arrays.asList(1, 2, 3);
List<String> strings = (List<String>) ints;

... この操作は可能ですが、安全ではないため、コンパイラは unchecked 警告を表示します。今あなたがするとき:

String s = ints.get(0);

ClassCastExceptionVM は を にキャストしようとするため、実行時に をInteger取得しますString

これは、コンパイラがジェネリックを含む上記のソース コードを次のコードと同等のものにコンパイルするために発生します。型消去は、すべてのジェネリック パラメータがなくなり、すべてのコレクションが のコレクションのみになるように実装されているObjectため、必要に応じてコードにキャストが挿入されます。

List ints = Arrays.asList(1, 2, 3);
List strings = ints;
String s = (String) ints.get(0);

3)

型パラメーターは、<T>メンバー フィールドとメンバー メソッドに対してのみ表示されます。たとえば、クラスがある場合、ジェネリック クラスの各インスタンスは異なる を持つことができTます。

class List<T> { // this is not java.util.List, just some custom class
    public List<T> subList(int start, int end) { ... }
    ...
}

...次に、次のことができます。

List<String> strings = ...
List<String> stringsSub = strings.subList(1, 2);

... だけでなく:

List<Integer> ints = ...
List<Integer> intsSub = ints.subList(1, 2);

ご覧のとおり、最初のインスタンスは にT設定されString、2 番目のインスタンスは に設定されていIntegerます。そのため、メンバー メソッドsubListは常にList同じを返しますT

ここで、静的フィールドを追加したとします。

class List<T> {
    public static List<T> CONSTANT_LIST = ...
    ...
}

...Tの場合はどうなりCONSTANT_LISTますか? StringInteger、何か他のもの?スタティックはどのクラス インスタンスとも独立して存在するため、定義することは不可能です。Tそれが彼らに見えない理由です。

一方、具体的なジェネリック型を持つ static を追加しても問題はありません。

class List<T> {
    public static List<Integer> CONSTANT_LIST = new List(1, 2, 3);
    ...
}
于 2012-09-09T16:41:40.607 に答える