2015-03-05 8 views
5

merkwürdige Situation Arraylist - unten ist der Code:"Warnung: [ungeprüft] ungeprüft cast", wenn Object Gießen <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 

Wenn Projekt (mit Compiler-Option -Xlint:unchecked in Projekteigenschaften) gebaut wird, erhalte ich eine Warnung:

Warnung: [ungeprüfter] ungeprüfter Guss
Arraylist list = (Arraylist) obj [1];
erforderlich: Arraylist
gefunden: Objekt

Aber in gleicher Weise String Gießen ist OK. Was ist das Problem hier?

Antwort

5

Dies liegt daran, dass der Compiler die internen Typen auf Listenebene nicht überprüfen kann. Daher müssen Sie zuerst nach der Liste suchen. Und die internen Typen individuell.

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

Es sollte ArrayList<?> list = (ArrayList<?>) obj[1];

+1

OK machen, aber wie später ändere es in 'ArrayList ' Typ, damit ich es an Methoden übergeben kann, die 'ArrayList ' benötigen (sonst wird der Code nicht kompiliert) ? Oder ich sollte diese Warnung einfach ignorieren? –

+1

@Ernestas Gruodis: Dies ist eine Einschränkung, die nicht ohne tiefgreifende, inkompatible Änderungen an der Java-Sprache * und * der JVM gelöst werden kann. Aber die Frage ist, warum Sie 'Object []' überhaupt verwenden. Javas Typsystem erlaubt es, die Objekttypen zu verfolgen, und wenn Sie sich bewusst dafür entscheiden, diese Typinformationen zu löschen, sollten Sie sich nicht über verlorene Typinformationen beschweren ... – Holger

+0

'Object []' weil die Methode verschiedene Datentypen zurückgibt. Das bedeutet, dass die Frage beantwortet wird. –

2

Dies liegt daran, wenn Sie versuchen, Integer in String umzuwandeln, erhalten Sie ClassCastException zur Laufzeit. Aber es wird kein Classcast hier:

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

Nein sein, habe ich definiert 'Arraylist ' überall .. –

+0

Ja hast du, aber die Laufzeit kann nicht wissen, das ist, warum es Sie, dass es warnt kann den generischen Typparameter des Cast nicht erzwingen. – eckes

+0

Ich glaube 'ArrayList ' ist ein konkreter generischer Typ. Um das oben genannte Problem zu vermeiden, muss man 'ArrayList ' –

2

Der Compiler beschwert

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

weil ein gegossenes eine Laufzeitprüfung ist. Zur Laufzeit könnte Ihr ArrayList<String[]> also ein ArrayList<Whatever[]> sein, weil der Typ von obj unbekannt ist.

Verwandte Themen