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.
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?
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:
Wie bei Ihrer ersten Frage kann ich die Diskrepanz oder die Warnmeldung in method2b
nicht verstehen.
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:
Aber so definiert in FinalAgent
:
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
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
Tags und Links java type-parameter