2013-06-08 6 views
8

は私がJavaでジェネリックを使用しますが、私はこのすべてをコンパイルし、作品ジェネリックタイプの標準リストより安全ですか?

public static void add(List l, Object o) { 
    l.add(o); 
} 

public static void main(String[] args) throws Exception { 
    List<Integer> list = new ArrayList<Integer>(); 
    add(list, "1.23"); 
    add(list, 1.23); 
    System.out.println(list); 
} 

を考えたとして、それはとても良いではありません。 listから値を取得すると、例外がスローされます。

Java 6ではより安全ですか?

+3

なぜあなたはしないでください:あなたはadd()メソッドのシグネチャを変更することができれば、あなたのmain()方法でコードのコンパイルエラーを取得するよう

しかし、あなたは単純に型チェックを強制することができます'list.add()'メソッドを使用しますか? 'List 'パラメータで 'add()'メソッドを宣言してください。 – NINCOMPOOP

+0

私は理解していますが、タイプ消去(古いコード)に直面しています –

+0

@ KalamarObliwy:しかし、コンパイル時のエラーからあなたを救うので、実行時に 'ClassCastExceptions'から保存されます。 – NINCOMPOOP

答えて

14

私は標準Collectionsを使用することをお勧め:

List<Integer> checked = Collections.checkedList(list, Integer.class); 

そしてちょうどcheckedに取り組みます。対応していないインスタンスを挿入する際に、以前よりも早く(したがってより良い)(つまり、検索中に)挿入されると、ClassCastExceptionがスローされます。

N.B.あなたのコンパイラのメッセージをチェックして、安全でない/チェックされていないコードに言及した警告がいくつか出てきたと思います。あなたの問題はコンパイラがあなたに伝えようとしているものです。 addの署名を制御する場合は、それを汎用にしてください。コンパイル時の安全性が得られます。

public static <T> void add(List<T> list, T t) { 
    list.add(t); 
} 
+0

+1は、 'Collections.checkedList()'の提案に対してです。しかし、 'add()'は宣言された型のサブタイプを挿入できるようにするべきです。リストが 'List 'として宣言されていれば、コンパイラは何かを追加できるようにします。したがって、 'List 'は 'List 'よりも適しています。 –

+0

OPが**リスト**に**を追加するだけの計画をしているなら、あなたは大丈夫です。私はもっ​​と一般的だと思っていた。 – emesx

+0

'add()'メソッドは一般的に*リストに*を追加するだけですが、2番目の考えでは、私は間違っていたと思います* :):コレクションと要素に関するもので、コンパイラによって透過的にスーパータイプに変換されます。私が言ったことは実際には2つの一般的な型にしか当てはまりません: 'A 'と 'B 'は不変であるためです。 –

3

私はそうは思わない。その静的なadd()メソッドが生きているという事実(あなたがコントロールしていないもの)であれば、JavaジェネリックがJava < 5.0と互換性があるように実装されているので、できることはあまりありません。

public static <T> void add(List<? super T> list, T object) { 
    list.add(object) 
} 
関連する問題