Java rekursive Typparameter und Vererbungsfehler in javac

8

Warum wird dieser Code nicht kompiliert?

%Vor%

Java 6 gibt diesen Fehler in handle(new ModifiedThingA()); :

%Vor%

Java 7 mag nicht einmal handle(new ThingA()); , das ist die Ausgabe von Java 7:

%Vor%

Es scheint mir, dass javac ModifiedThingA für BaseThing<ModifiedThingA> falsch interpretiert, wenn es tatsächlich ein BaseThing<ThingA> ist. Ist das mein Fehler oder javac ?

    
Jesse 21.08.2012, 15:34
quelle

3 Antworten

1
Das Verhalten von

javac scheint korrekt zu sein. Theoretisch wäre eine Typvariable, T , ausreichend. Sie haben jedoch eine zweite Typvariable, X , eingeführt, um die Inferenz entlang zu typisieren. Das Argument für X wird zuerst abgeleitet und dann wird basierend auf dem Aufrufkontext das Argument für T abgeleitet:

%Vor%

Ihr Aufrufkontext setzt jedoch keine Grenzen für den Rückgabetyp. Daher ist der Compiler forced um eine Typvariable ( CAP#1 ) mit dem Null-Typ als untere Grenze einzuführen. T 's Argument wird als glb(BaseThing<CAP#1>) = BaseThing<CAP#1> abgeleitet. Mit der unteren Grenze ist X nicht nachweisbar ein Subtyp von T .

Es gibt zwei oder drei Wege daraus.

  1. manuell folgern (okay, wenn selten notwendig)
  2. liefert eine "Überladung" mit dem Rückgabetyp void (benötigt einen anderen Namen, urgh)
  3. Wenn die zurückgegebene Liste unveränderlich oder eine defensive Kopie ist, können Sie das Typargument T von seinem Begrenzungsargument
  4. trennen

Ich bevorzuge Option 3:

%Vor%

Glückliche Generika.

    
Ben Schulz 21.08.2012, 18:48
quelle
1

Ihr Code kompiliert in javac 1.8.0_45 und Eclipse 4.1.1.

Wahrscheinlich haben die Änderungen, die an den Typ-Inferenz-Algorithmus in Java 8 vorgenommen wurden, um Lambda-Ausdrücke auf eine nette Art zu kompilieren, auch Ihr Problem gelöst.

    
Lii 04.11.2015 12:44
quelle
0

Es scheint einen Fehler in javac 1.7.0_09 und 1.7.0_11 zu geben, der dieses Problem verursacht.

    
Ivan Hristov 21.01.2013 16:48
quelle

Tags und Links