Problem mit Java-Typparametern für Rückgabewerte

8

Ich habe versucht, dieses Problem auf die kleinste Menge an Code zu reduzieren, die ich konnte.

Ich habe eine Tabellenstruktur wie eine Datenbanktabelle mit den Klassen Row und Table definiert. A Table ist im Wesentlichen eine Liste von Row . Ich möchte, dass Unterklassen ihren speziellen Geschmack von Table und Row definieren, und ich möchte, dass der Compiler unangemessene Versuche findet, Zeilen eines Typs in Tabellen eines inkompatiblen Typs einzufügen.

Die Klasse abstract Agent stellt eine Methode bereit, um Parameter zu übernehmen und eine Tabelle zurückzugeben, die Zeilen vom Typ T enthält. Ich habe drei Methoden definiert, um das Problem zu veranschaulichen, das ich habe.

Die Klassen FinalAgent , FinalTable und FinalRow definieren Implementierungen der Klassen Agent , Table und Row . Letztendlich möchte ich method2a , was eine Liste von Parametern enthält und eine Tabelle vom Typ FinalTable zurückgibt.

%Vor%

Unten:

  • method1 von FinalAgent kompiliert, aber ich muss Table<FinalRow> t1 = new FinalAgent().method1(null); schreiben, um die Methode aufzurufen.
  • method2a von FinalAgent Ich habe den Rückgabetyp in FinalTable geändert, um das wiederzugeben, was ich tatsächlich zurückgebe (ich möchte FinalTable t2a = new FinalAgent().method2a(null); schreiben), aber der Compiler erzeugt den Fehler: Die Methode method2a (List) von type FinalAgent muss eine übergeordnete Methode überschreiben oder implementieren
  • method3 Ich habe den Parameter von List auf String geändert. Die Methode kompiliert OK, gibt mir aber eine Typsicherheitswarnung, mit der ich zumindest arbeiten kann.

So, schließlich die Frage: Ist es ein Compiler-Fehler, der method2a in FinalAgent noch nicht kompiliert hat? method2b kompiliert?

Ich könnte auch fragen, gibt es einen besseren Weg zu tun, was ich tue?

    
John Jackson 05.10.2016, 21:41
quelle

3 Antworten

8

Es ist nicht klar, warum Sie die Methoden parametrisieren. Sie versprechen, eine Table<T> zurückzugeben, aber Ihre Methode kann T zur Laufzeit wegen Typlöschung nicht identifizieren. Wahrscheinlich möchten Sie stattdessen die gesamte Klasse Agent parametrisieren:

%Vor%

Wie bei Ihrer ersten Frage kann ich die Diskrepanz oder die Warnmeldung in method2b nicht verstehen.

    
shmosel 05.10.2016 22:10
quelle
1

Die Verwendung eines Methodenparameters an einer einzigen Stelle bedeutet, dass der Parameter normalerweise nicht erforderlich ist

Bei Methoden wie dieser in Agent , FinalAgent wird gut übersetzt:

%Vor%     
k5_ 05.10.2016 22:19
quelle
1

Dies ist die direkte Folge des Rohtyps.

  • method1 ist immer noch eine generische Methode: kein Problem.
  • method2b ist keine generische Methode mehr, sondern überschreibt die Methode in Agent : kein Problem (außer der Sicherheitswarnung aufgrund der ungeprüften Konvertierung)
  • method2a ist keine generische Methode mehr, aber überschreibt nichts

method2a wird wie folgt von FinalAgent nach der Kompilierung deklariert:

%Vor%

Aber so definiert in FinalAgent :

%Vor%

Und jetzt bist du fest . Gleiches Löschen, überschreibt jedoch nicht richtig method2a

Hier ist ein einfaches Beispiel:

%Vor%

Es gibt The method bar(List<String>) of type FooChild must override or implement a supertype method

%Vor%

Es gibt Name clash: The method bar(List<String>) of type FooChild has the same erasure as bar(List) of type Foo but does not override it

Ein anderes Beispiel. Dieser Code wird gut übersetzt:

%Vor%

Dies tut nicht:

%Vor%

Es gibt Name clash: The method bar(List<String>) of type FooChild has the same erasure as bar(List<String>) of type Foo but does not override it

Sobald bar zu einer generischen Methode wird, wird sie mit rohen Typen angezeigt und wir können das gleiche Problem feststellen.

Ein anderes Beispiel für ein Problem mit dem Rohtyp: Name beim Überschreiben der Methode der generischen Klasse

    
ToYonos 14.10.2016 16:20
quelle

Tags und Links