2016-05-06 19 views
5

私は可変引数と匿名内部クラスと一般的な配列をインラインで作成する方法を発見した:Javaでvarargsを使ってジェネリックアレイを作成する潜在的なリスクは何ですか?

Unchecked generics array creation for varargs parameter 
:(IntelliJの中)コード検査が言うながら

import java.util.Arrays; 
import java.util.Objects; 

public class GenericArrayCreate<C> { 

    public void method() { 

     C[] ans = new Object() { C[] c(int length, C ... cs) { return Arrays.copyOf(cs, length); }}.c(10); 

     System.out.println(ans.length); 
     System.out.println(Objects.toString(ans)); 

    } 

    public static void main(String[] args) { 
     new GenericArrayCreate<Class<? extends Integer>>().method(); 
    } 
} 

Javaコンパイラは、このコードには警告を生成します

ここで何が起こっているのですか、なぜそれが誓いますか?

答えて

1

コード検査では、varargsはarrayで実装されており、arrayはgenericsをサポートしていないため注意が必要です。しかし、これを追加することで警告を抑制できます:

@SuppressWarnings("unchecked") 

なぜこのようなことが起こるのは、情報が失われることがあるからです。その詳細についてはhereを読むことができます。

3

内部的にこのコードを試してみてください

を "オブジェクト" の配列の代わりに、 "C" の配列を作成している:

public static <C> C[] method(int number) { 
    return new Object() { 
    C[] create(int length, C ... cs) { 
     return Arrays.copyOf(cs, length); 
    } 
    }.create(number); 
} 

public static void main(String[] args) { 
    System.out.println(Main.<Integer>method(10)); 
    System.out.println(new Integer[10]); 
} 

[Ljava.lang.Object; 6bc7c054

@

[Ljava.lang.Integer; 232204a1

@あなたは彼らが同じではありません見ることができるように。

あなたはこれらのような何か実行する場合ので、それは危険です:

public static void main(String[] args) { 
    Integer[] integerArray1 = Main.<Integer>method(10); 
    Integer[] integerArray2 = new Integer[10]; 
} 

をそして、あなたはClassCastExceptionがあります

[Ljava.lang.Object。 [Ljava.lang.Integer

にキャストすることはできませんあなたは、アレイを構築するためにクラスを送信する必要が配列の任意の種類を作成したい場合は、このようにそれを行うことができます。

public static <C> C[] method(Class<C> clazz, int number) { 
    return (C[]) Array.newInstance(clazz, number); 
} 

public static void main(String[] args) { 
    Integer[] integerArray1 = Main.<Integer>method(Integer.class, 10); 
    Integer[] integerArray2 = new Integer[10]; 
} 
+0

@私の答えについてのコメントを薄暗くする? – Troncador

関連する問題