2011-10-22 7 views
15

Java 7では、変更不可能なvarargsパラメータを使用してメソッドをコンパイルするときに警告を表示しないように、@SafeVarargs注釈を付けることができます。 Project Coinのproposalは、varargsパラメータと同じ型の要素だけがvarargs配列に格納されることを確実にする場合にアノテーションを使用するように規定しています。Java 7でのVarargsメソッド呼び出しの簡略化

安全ではない方法の例を教えてください。

答えて

21

例えば、foo()は安全ではない、それは@SafeVarargsとマーキング方法によるもの[2]

<T extends List<?>> void foo(T... args) 
{ 
    List<String>[] array2 = (List<String>[])args; 
    array2[0] = a_list_of_string; 
} 

void test2() 
{ 
    List<Integer>[] args = ...; // [1] 
    foo(args); 
    Integer i = args[0].get(0); // [2] 
} 

で問題を引き起こし、アレイ内の非Tを格納することができる、あなたがあることをコンパイラに約束そんなにいたずらなことはしないでください。


しかし、[1]でジェネリックアレイを作成するにはどうしたらいいですか? Javaは一般的な配列の作成を許可していません!一般的な配列の作成の

ザ・唯一の認可方法

foo(list_int_1, list_int_2) 

可変引数メソッドを呼び出しているときに、アレイは、発信者がアクセスできない、呼び出し側が行うことはできません[2]とにかく、それは問題ではありません。どのようにfoo()が配列に混乱しますか。

しかし、その後、あなたはそれについて考える、それだから我々はすべての後に、一般的な配列を作成することができます

@SafeVarargs 
static <E> E[] newArray(int length, E... array) 
{ 
    return Arrays.copyOf(array, length); 
} 

List<String>[] array1 = newArray(10); 

と、一般的な配列リテラル

@SafeVarargs 
static <E> E[] array(E... array) 
{ 
    return array; 
} 

List<String>[] array2 = array(list1, list2); 

一般的な配列を作成するためのバックドアです。 ..愚かなJava、私たちがそれをやめないようにしようとしています。

+1

varargsメソッドを使用しない汎用配列を作成できますが、[Array#newInstance(Class type、int length)](http://tinyurl.com/3uzbb7v)を使用してキャストしなければなりません。徹底的な答えをありがとう。 – Jeffrey

+0

実際は「単純化」ではなく、ヒントが改善されました。 –

+0

私はこの例を試していますが、@SafeVarargsを使用する場合と使用しない場合の動作に変更はありません。私はまだ警告を受ける "タイプの安全性:リストの一般的な配列 ...." – excalibur

関連する問題