2013-10-16 16 views
5

Nehmen wir an, wir haben eine Java-Anwendung mit einer abstrakten Klasse namens SomeAbstractClass und mindestens 10 Unterklassen dieser Superklasse.Was ist die Verwendung von Sammlung <? extends SomeAbstractClass> anstelle von Collection <SomeAbstractClass>

Was ist die Verwendung dieses abstrakte Superklasse in Generika in der Art und Weise mit Collection<? extends SomeAbstractClass> statt nur Collection<SomeAbstractClass>

mit vielleicht etwas sehr grundlegende Sachen innerhalb Generika ich verpasst.

+0

Lesen Sie diese. Genau das, was Sie wissen wollen. Http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html –

+0

"Der Begriff List ist restriktiver als List , weil ersteres einer Liste entspricht nur vom Typ Number, wobei letzteres mit einer Liste vom Typ Number oder einer seiner Unterklassen übereinstimmt. " Von der Ressource, SURESH oben verlinkt. – Fildor

+0

Sie können sich das ansehen. http://www.thejavadeek.com/2013/08/28/generics-the-wildcard-operator/ –

Antwort

4

Der Unterschied zwischen diesen beiden Erklärungen:

Collection<? extends A> c1; 
Collection<A> c2; 

Ist das c2 Instanzen von A oder jede Unterklasse halten kann, aber c1 können Instanzen von einem unbekannten, aber besondere Unterklasse von A halten (oder A) oder einer der Unterklassen der unbekannten Klasse.

Sie keine Elemente hinzufügen können, um c2, da der Compiler nicht weiß, welche Art es ist, nur dass, wenn Sie ein heraus es bekommen kann

Weitere A. gegossen werden, können Sie nicht zuweisen (dh cast) c1 bis c2 - c1 ist keine Unterklasse des c2-Typs.

-2

In Ihrem Fall macht es keinen Unterschied, da die Art abstrakt ist, aber im Allgemeinen kann Collection<SomeClass>SomeClass und all seine Unterklassen enthält, während Collection<? extends SomeClass> nicht SomeClass enthalten kann, aber nur Subklassen es ist.

Sie können es selbst ausprobieren.

List<Number> foo = new ArrayList<>(); 
foo.add(Integer.valueOf(0)); 

Arbeiten während

List<? extends Number> foo = new ArrayList<>(); 
foo.add(Integer.valueOf(0)); 

nicht der Fall ist. Es zeigt den Fehler "The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (Integer)"

+2

-1 völlig inkorrekt. Die generische Grenze '? extends X 'enthält' X' - es kann auch Instanzen von 'X' enthalten. Und es gibt kein Apostroph in "its" ... also dort – Bohemian

+0

"Der Begriff List ist restriktiver als List , weil ersteres eine Liste vom Typ Number trifft, während letzteres einer Liste vom Typ Number oder entspricht jede seiner Unterklassen. " von http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html erzählt eine andere Geschichte ... – Fildor

+0

@Fildor das klingt ein bisschen seltsam für mich, da es definitiv nicht das tatsächliche Verhalten entspricht. Siehe das Beispiel von meiner Bearbeitung. –

0

Die unten ist not true in generics,

Collection<? extends SomeAbstractClass> 
      ^
       | 
       | 
Collection<SomeAbstractClass> 

Collection<? extends SomeAbstractClass> und Collection<SomeAbstractClass> sind völlig unterschiedliche Typen und nicht verwandt.

Beachten Sie, dass,

Gegeben seien zwei konkrete Typen A und B (zum Beispiel Anzahl und Integer), MyClass hat keine Beziehung zu MyClass, unabhängig davon, ob nicht A und B sind miteinander verwandt.

Zum Beispiel List<Integer> ist kein Subtyp von List<Number> obwohl Integer ein Subtyp der Nummer ist.

1

Platzhalter in Generics sind für Collection Type und in der Regel nicht für Elemente gespeichert.

Stellen Sie sich zum Beispiel eine Methode vor, die Argument List<Number> übernimmt.

public void calculateSum(List<Number> numbers) { 
    for (Number n: numbers) { 
     // calculate Sum 
    } 
} 

Nun, wenn wir wollen, indem List<Integer> Summe ganzer Zahlen wie folgt berechnen.(Beachten Sie, dass Integer ist eine Unterklasse von Number)

List<Integer> integers= new ArrayList<Integer>(); 
//Populate collection 
calculateSum(integers); //Error 

Dies wird nicht als selbst arbeiten, obwohl Integers ist ein Subtyp von NumberList<Integers> ist kein subType von List<Number>. Beachten Sie, dass List<Number> noch speichern kann Integer, Float, Double usw.

Also, um eine generische Methode, um die Summe von jeder Art von Number wir Wildcard berechnen verwenden als

public void calculateSum(List<? extends Number> numbers) { 
    for (Number n: numbers) { 
     // calculate Sum 
    } 
} 

folgt Dies wird die Berechnung der Summe von jeder Art von Zahlen zur Verfügung gestellt, dass der Typ erweitert Number

Verwandte Themen