Ist eine String-Array-Unterklasse eines Object-Arrays?

7

Ich denke, ich vermisse hier etwas Grundlegendes. Jede Erklärung oder Hinweise auf zuvor gestellte Fragen werden sehr hilfreich sein.

%Vor%

Es scheint also, als wäre eine List<String> keine Unterklasse von List<Object> , aber eine String[] ist eine Unterklasse von Object[] .

Ist das eine gültige Annahme? Wenn ja warum? Wenn nicht, warum?

Danke

    
Kal 11.01.2012, 19:29
quelle

5 Antworten

10

Java-Arrays sind kovariant , d. h. sie erlauben Object[] foo = new String[2]; . Aber das bedeutet nicht, dass sie Unterklassen sind. String[] ist eine Unterklasse von Object (obwohl instanceof wahr liefert, String[].class.getSuperclass() gibt Object zurück)

    
Bozho 11.01.2012, 19:32
quelle
5

Ja, Ihre Annahme ist gültig. Wie von @ Bozho Arrays angegeben sind kovariant, während generische Sammlungen (wie generische Liste) nicht kovariant sind.

Kovarianz in Arrays ist riskant:

%Vor%

Die dritte Zeile löst eine Laufzeitausnahme aus. Wenn diese Ausnahme nicht ausgelöst würde, könnten Sie eine String Variable, s , erhalten, die auf einen Wert verweist, der kein String ist (noch ein Subtyp davon): a Date .

    
Itay Maman 11.01.2012 19:41
quelle
3
%Vor%     
maerics 11.01.2012 19:34
quelle
3

Sie haben Recht. Array-Typen sind in Java kovariant nach Entwurf, aber ein Foo<Sub> ist-nicht-ein Foo<Super> .

    
pholser 11.01.2012 19:35
quelle
2
  

String [] ist eine Unterklasse von Object []

Richtig, siehe 4.10.3 Untertypen zwischen Array-Typen :

  

Wenn S und T beide Referenztypen sind, dann S [] & gt; 1 T [] falls S & lt; 1 T.

Seit String >1 Object so String[] >1 Object[]

Das heißt, String[] ist ein direkter Subtyp von Object[]

  

Objekt & gt; 1 Objekt []

Dafür Object > String[] ; String[] ist ein (indirekter?) Subtyp von Object

Es gibt keine solche Beziehung für Generika, also ist List<String> > List<Object> nicht wahr.

Betrachten Sie nun das folgende einfache Beispiel:

%Vor%

Es kompiliert nicht, weil x allF mit List<C> aufruft, was nicht a List<I> ist. Um List<C> verwenden zu können, muss sich die Signatur leicht ändern:

%Vor%

Jetzt kompiliert es. Informell ist li ein List von einige -Typen, die I erweitern / implementieren. So ist List<C> zu List<? extends I> zuweisbar. Was Sie mit einer solchen Liste machen können, ist begrenzt. Im Wesentlichen können Sie lesen / darauf zugreifen, aber nicht write/modify it.

    
Miserable Variable 11.01.2012 20:48
quelle

Tags und Links