Problem mit 'extends' und 'super' in Java Generics mit generischen Methoden

8

Es gibt eine Methode:

public static <T> void addandDisp(Collection<T> cs, T t)

wird wie folgt aufgerufen:

%Vor%

Dies ergibt einen Kompilierzeitfehler. Auf der anderen Seite, wenn wir nur einen Parameter hatten, ist der Aufruf erfolgreich. Warum ist das so?

Außerdem ist das erfolgreich:

%Vor%

dies ist nicht:

%Vor%

Was ist die zugrunde liegende Logik?

    
Daud 04.08.2014, 14:24
quelle

4 Antworten

1
  

Auf der anderen Seite, wenn wir nur einen Parameter hatten, ist der Aufruf erfolgreich. Warum ist das so?

Ihre Methode hat einen einzelnen Typparameter. Wenn Sie eine Methode aufrufen, geben Sie entweder explizit ein Typargument an oder leiten es implizit ab.

Wenn Sie es wie

aufrufen %Vor%

Der Compiler muss einen Typ extrahieren, der von beiden Methodenargumenten an T gebunden wird, da beide Methodenparameter vom Typparameter der Methode, T , abhängig sind.

Das Problem hierbei ist, dass ? extends Object und Object keinen einzigen Typ erzeugen, der sicher an T gebunden werden kann. Stell dir vor du hättest

%Vor%

Dieser add sollte nicht erlaubt sein, da ein Object nicht verwendet werden sollte, wenn ein Number erwartet worden wäre. Type Sicherheit würde brechen.

Wenn Sie einen einzelnen Parameter haben

%Vor%

Dann verwendet der Compiler das Argument Argument, um das Argument type zu ermitteln. Es gibt dann keine Zweideutigkeit darüber, was zu verwenden ist.

    
Sotirios Delimanolis 04.08.2014, 15:20
quelle
11

Ich würde annehmen, dass addandDisp hinzufügen und anzeigen bedeutet.

Wenn Sie eine Sammlung haben, definiert als:

%Vor%

Dies bedeutet, dass der Compiler es Ihnen erlaubt, die Sammlung allen möglichen unbekannten Subtypen von Object zuzuweisen. Da Sie die Operation add haben, verweigert Ihnen der Compiler grünes Licht, weil er nicht weiß, ob der Typ des angegebenen Objekts der Einschränkung des unbekannten Subtyps von Object entspricht. Dies wird Kovarianz genannt.

Ähnlich, wenn Sie eine solche Definition haben:

%Vor%

Mit dem Compiler können Sie ls1 an:

übergeben
  • LinkedList<String>(); //you can add Strings to the list
  • LinkedList<Object>(); //you can add Strings and Objects to the list

In diesem Fall erkennt der Compiler vollständig, ob das Objekt, das Sie übergeben möchten, die Bedingung erfüllt, dass es sich um den Subtyp des generischen Typs der Sammlung handelt. Dies nennt man Kontravarianz .

Weitere Informationen:

Konstantin Yovkov 04.08.2014 14:30
quelle
2

Hier ist ein anderer Ansatz, aber andere gaben eine ziemlich detaillierte Antwort.

Das erste Beispiel:

%Vor%

Hier kann ls0 von jedem Typ sein, der eine Unterklasse von Object ist, wie ein Number , wie Ihr Beispiel zeigt.

Was wäre, wenn das funktionieren könnte? Es würde bedeuten, dass wenn Sie eine Object in eine der Sammlungen einfügen können.

Stellen Sie sich vor, ich möchte Ihre vorherige Liste von Number -Objekten iterieren:

%Vor%

Wenn ich hier ein Object setzen könnte, dann Plaff! würde ich sofort eine Klassenausnahme erhalten.

Das zweite Beispiel

%Vor%

Lassen Sie uns ein wenig mit der Objekthierarchie spielen: String ist eine Unterklasse von CharSequence , die eine Unterklasse von Object ist.

Sie erhalten ls1 hier, was ein unbekannter Übertyp von String ist (z. B. ein CharSequence ). Ist es in Ordnung, ein String in eine Liste von Zeichenfolgen zu setzen? Ja, es ist okay, da sie die gleiche Schnittstelle teilen! Du kannst sie auf dieselbe Art und Weise damit umgehen.

Das dritte Beispiel

%Vor%

Nehmen wir die vorherige Situation an: Sie weisen ls1 eine Liste von CharSequence s zu. Können Sie einem List<CharSequence> ein Objekt hinzufügen? Nein, aus dem gleichen Grund wie das erste Beispiel fehlschlägt.

Hoffe, dass hilft, Ihre Probleme ein wenig zu klären: -)

    
rlegendi 04.08.2014 15:19
quelle
0

1 Beispiel: Object ist nicht ? extends Object (z. B. Number ist ? extends Object , aber Object ist nicht Number ). Daher ist es nicht typsicher.

2 Beispiel: String ist ? super String . Es ist typsicher.

3 Beispiel: Object ist nicht ? super String . Nicht wieder sicher.

    
kraskevich 04.08.2014 14:30
quelle

Tags und Links