Ich möchte bestimmte Tests in Listen ausführen. Die Listen können völlig verschiedene Klassen enthalten.
Ich habe eine Methode, um die Konsistenz der Liste zu überprüfen - nicht null, nicht leer, nicht mehr als x Elemente. Dies ist allen Listen gemeinsam. Dann möchte ich jedes der Objekte mit Überladung testen.
Die Idee wäre etwas wie:
%Vor%und dann
%Vor%Aber ich musste auch eine Methode wie folgt hinzufügen:
%Vor%Und das wurde zur Laufzeit aufgerufen - nicht meine anderen Methoden mit den spezifischen Klassen. Obwohl die Klasse genau gleich war. Offensichtlich fehlt mir etwas Generikaverständnis.
Wenn ich jetzt die allgemeine Methode nicht benutze und versuche, sie so zu lösen:
%Vor%Compilerfehler - "Methodencheck (Liste) hat die gleiche Löschprüfung (Liste) wie eine andere Methode ..."
Gibt es dafür eine elegante Lösung? Ich könnte einfach andere Methodennamen verwenden, würde aber gerne wissen, wie es ohne das möglich ist.
Danke!
Da der Typ der Variablen in check(List<T> list)
verloren geht, haben Sie zwei Möglichkeiten:
1. Führen Sie verschiedene Aktionen durch, indem Sie den Laufzeittyp
überprüfen %Vor% Dies kann etwas ausgeklügelter sein, zum Beispiel indem man jeden Check in Callable
einpackt und Map<Class, Callable>
Dies ähnelt dem Besuchermuster.
2. Aufrufen einer virtuellen Methode für das selbst zu überprüfende Element
Wenn die Prüflogik an das zu überprüfende Objekt übergeben werden kann (das ist nicht unbedingt eine schlechte Sache), müssen Sie die Typen nicht überprüfen:
%Vor%Dann:
%Vor%Dies sind nur die zwei Optionen. Jede Implementierung muss eine Variation einer dieser
sein Dies ist nichts über Generika, die Sie vermissen. Java hat keinen doppelten Versand . Der Aufruf von check
muss zur Kompilierzeit aufgelöst werden, und check(T)
ist die einzige Übereinstimmung, da der Compiler in einem gegebenen Szenario nicht feststellen kann, ob T
SomeType
oder SomeOtherType
ist. Es muss eine Methode zum Aufrufen ausgewählt werden, die für alle möglichen T
s funktioniert.
Dies wird manchmal mit dem Besuchermuster gelöst.
Bei Generics wird der Typ-Parameter während der Kompilierung tatsächlich gelöscht, und das Listenobjekt weiß nichts über den statischen Typ des Objekts, das es enthält. Da es es nicht kennt, kann es keine Überladung verwenden, um Methoden mit unterschiedlichen Parametern aufzurufen, da Java Mehrfachversand nicht unterstützt .
Sie haben dann drei Möglichkeiten:
Checked
-Schnittstelle mit einer Prüfmethode implementieren, die die Prüflogik ausführt. Nachteil ist, dass die Prüflogik jetzt an mehreren Stellen verteilt ist und es nicht praktisch ist, wenn Sie Objekte von Klassen haben, die Sie nicht kontrollieren können. instanceof
, um explizit die check
Methoden entsprechend dem dynamischen Typ des Objekts aufzurufen. Nachteil ist, dass Sie am Ende einen großen if / else-Block haben, der etwas schwieriger zu warten ist. check
Logik bleibt an einem einzigen Ort.