2014-10-08 9 views
19

erwarteten Warum ist der println Druck „tom“ und keine Laufzeitausnahme zeigt, nachdem auf List<Integer> Gießen, während sie nicht in der Lage ist, den Wert 1 nach dem Gießen zu List<String> drucken?Generics Liste <String> und Liste <Integer> verhalten nicht als

import java.util.Arrays; 
import java.util.List; 

public class Main { 
    public static void main(String args[]) { 

     List list = Arrays.asList(1, "tom"); 

     System.out.println(((List<Integer>) list).get(1)); 
     // "tom" 

     System.out.println(((List<String>) list).get(0)); 
     // ClassCastException: Integer cannot be cast to String 
    } 
} 
+5

Es * zeigt * Laufzeit Ausnahme. – Maroun

+0

einen Listentyp gleichzeitig auskommentieren, um die gewünschte Ausgabe zu erhalten, d. H. // Liste list3 = list1; // System.out.println (list3.get (0)); – Aman

Antwort

34

Der erste Anruf von println wird PrintStream.println(Object) und der zweite Anruf PrintStream.println(String) abgesendet wird statisch geschickt. Für den zweiten Aufruf setzt der Compiler eine implizite Umwandlung auf String, die dann zur Laufzeit mit ClassCastException fehlschlägt.

+3

Das ist die richtige Antwort, +1. – Maroun

+2

Könnten Sie bitte dies näher ausführen, bcoz, was ich denke im ersten Fall shud gehen PrintStream.println (Integer) gehen, wenn PrintStream.println (String) für den zweiten Fall oder beide Shud PrintStream.println (Object) geht. – Aman

+7

Es gibt keine 'PrintStream.println (Integer)'. Der Compiler sendet immer an eine Methode mit der spezifischsten Signatur. Der spezifischste Typ für "Integer" ist "Object", und der spezifischste Typ für "String" ist "String". – ZhekaKozlov

0
Integer i = new Integer(101); 
String s = new String(i); // undefined and Invalid 
StringBuffer sb = new StringBuffer(i); // defined and Valid 

String s2 = "tom"; 
Integer i2 = new Integer(s2); //defined and valid 

Also, wenn Sie eine nicht generische Liste zu einem generischen zuweisen zugewiesen wird, aber wenn Sie es drucken, überprüft es für die Typsicherheit oder Konstrukteuren definieren zum Gießen, ob es gültig und definiert Konstrukteuren dann wird es gedruckt sonst Zeigt die Klassenübergabe-Ausnahme an, da die Klasse aufgrund fehlender undefinierter Konstruktoren für das Casting nicht gegossen werden kann.

Wenn ich falsch bin mir bitte helfen mit der richtigen Logik heraus ...

+0

Das hat nichts mit Konstrukteuren zu tun. – Radiodef

0

Diese Art von Problem durch Verwendung von Generika vermieden werden kann und ist die primäre Motivation für die Verwendung von Generika.

Dies ist der eigentliche Fluss des Codes, von Ihrer zweiten println() Sicht:

  1. Ihr Code ein ArrayList vom Typ erklärt Object;

  2. Es fügt eine Integer und eine String zu der ArrayList hinzu.

  3. Es wirft Ihre Liste auf eine String Liste. Ihre Liste ist als auf String beschränkt gekennzeichnet.

Java Generika sind eine Kompilierung-Funktion nur so Ihre Liste kann String und Integer Elemente ohne Probleme akzeptiert. Das Objekt selbst weiß nichts darüber, welche Typen es im Gegensatz zum Compiler enthalten soll.

  1. Es attemps das erste Element des gegossenen Liste retreive, die ein String sein soll und es String implizit gegossen.

  2. Anrufe println(String x) von PrintStream Klasse.

Aber das erste Element ist eigentlich kein String und ist ein Integer. Sie können Integer nicht in String umwandeln.

Lesen Sie Generics in Java Motivationsbeispiel.

Verwandte Themen