Überladen / Generics in Java

8

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!

    
Ixx 30.01.2013, 15:55
quelle

5 Antworten

1

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>

verwendet

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     
Miserable Variable 30.01.2013, 18:27
quelle
9

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.

    
Mark Peters 30.01.2013 16:00
quelle
4

Das Problem sollte vom Anrufer gelöst werden. Wenn Sie Ihre Klasse mit einem konkreten Typ für T instanziieren, sollte sie auch eine Instanz von Checker<T> mit demselben konkreten Typ übergeben:

%Vor%     
JB Nizet 30.01.2013 16:02
quelle
4

Sie können instanceof zum Versenden verwenden:

%Vor%     
jacobm 30.01.2013 16:00
quelle
2

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:

  • Lassen Sie Ihre Objekte eine 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.
  • Verwenden Sie 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.
  • Implementieren Sie das Besuchermuster . Nachteil ist, dass Sie auch die Objektklassen ändern müssen, aber die check Logik bleibt an einem einzigen Ort.
Cyrille Ka 30.01.2013 16:01
quelle

Tags und Links