2016-05-06 14 views
5

znalazłem sposób, aby utworzyć rodzajowe inline tablicę z varargs i anonimowej klasy wewnętrznej:Jakie są potencjalne zagrożenia związane z tworzeniem ogólnej tablicy z varargs w Javie?

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(); 
    } 
} 

kompilator Javy nie wytwarza żadnego ostrzeżenia o tym kodzie, natomiast inspekcja kodu (w IntelliJ) mówi:

Unchecked generics array creation for varargs parameter 

Co się tutaj dzieje i dlaczego przeklina?

Odpowiedz

1

Inspekcja kodu zauważy, że ponieważ varargs są zaimplementowane z tablicą, a tablica nie obsługuje generycznych. Możesz jednak wyłączyć to ostrzeżenie, dodając:

@SuppressWarnings("unchecked") 

Powodem, dla którego tak się dzieje, może być utrata informacji. Możesz przeczytać więcej na ten temat here.

3

wewnętrznie tworzony tablicę "obiekt" zamiast macierzy "C"

Spróbuj kod:

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

Jak widać nie są one takie same.

Jest to niebezpieczne, ponieważ jeśli uruchomić coś, takie jak:

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

i trzeba będzie ClassCastException

[Ljava.lang.Object; nie mogą być oddane do [Ljava.lang.Integer

Jeśli chcesz stworzyć każdy rodzaj tablicy trzeba wysłać klasę skonstruować tablicę, możesz zrobić to tak:

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

@ Dims komentarz na temat mojej odpowiedzi? – Troncador

Powiązane problemy