2015-03-05 13 views
5

dziwna sytuacja - poniżej kod:„Ostrzeżenie: [zaznaczone] niezaznaczone cast” podczas rzucania obiektu do ArrayList <String[]>

ArrayList<String[]> listArr = new ArrayList<>(); 
Object[] obj = new Object[]{"str", listArr}; 

String str = (String) obj[0];//OK 
ArrayList<String[]> list = (ArrayList<String[]>) obj[1];//warning: [unchecked] unchecked cast 

Kiedy projekt jest zbudowany (z opcją kompilatora -Xlint:unchecked we właściwościach projektu), mam jednego Uwaga:

uwaga: [zaznaczone] zaznaczone obsada
ArrayList lista = (ArrayList) należy oBJ [1];
wymagane: ArrayList
znaleziono: Object

Ale odlewania ciąg w taki sam sposób, jest OK. Jaki jest tutaj problem?

Odpowiedz

5

Dzieje się tak dlatego, że kompilator nie może zweryfikować typów wewnętrznych na poziomie listy, dlatego należy najpierw zweryfikować listę. I typy wewnętrzne indywidualnie.

Zamiast ArrayList<String[]> list = (ArrayList<String[]>) obj[1];

Powinno być ArrayList<?> list = (ArrayList<?>) obj[1];

+1

OK, ale jak później zmienić go na 'ArrayList ' typ, więc mógłbym przekazać go metodom, które wymagają 'ArrayList ' (w przeciwnym razie kod się nie skompiluje) ? Czy powinienem po prostu zignorować to ostrzeżenie? –

+1

@Ernestas Gruodis: Jest to ograniczenie, którego nie można rozwiązać bez głębokich, niekompatybilnych zmian w języku Java * i * JVM. Ale pytanie brzmi: dlaczego w ogóle używasz 'Object []'. System typu Java pozwala śledzić typy obiektów i jeśli celowo zdecydujesz się usunąć informacje o typie, nie powinieneś narzekać na utratę informacji o typie ... – Holger

+0

'Object []' ponieważ metoda zwraca różne typy danych. Oznacza to, że odpowiedź na to pytanie. –

2

Dzieje się tak, ponieważ jeśli spróbujesz rzucić Integer na String, otrzymasz ClassCastException w czasie wykonywania. Ale nie będzie ClassCastException tutaj:

ArrayList<Integer[]> listArr = new ArrayList<>(); 
    ArrayList<String[]> list = (ArrayList<String[]>) obj[1]; 
+0

Nie, zdefiniowaliśmy 'ArrayList ' wszędzie .. –

+0

Tak zrobiłeś, ale środowisko wykonawcze nie może wiedzieć, to dlaczego jest ostrzeżeniem, że to nie może wymusić ogólnego parametru typu rzutowania. – eckes

+0

Wierzę, że 'ArrayList ' jest typem typu konkretnego. Aby uniknąć powyższego problemu, trzeba zrobić "ArrayList " –

2

Kompilator narzeka

ArrayList<String[]> list = (ArrayList<String[]>) obj[1] 

ponieważ obsada jest sprawdzenie czasu wykonywania. Tak więc w czasie wykonywania Twój ArrayList<String[]> może być ArrayList<Whatever[]>, ponieważ typ obiektu jest nieznany.

Powiązane problemy