Ich habe einige Enums, die eine gemeinsame Schnittstelle implementieren, und ich möchte das Klassenliteral von der Methode zurückgeben. Ich kann den Schnitttyp jedoch nicht korrekt angeben. Siehe unten das Codebeispiel, das das Problem veranschaulicht.
%Vor% #getEnum1
Methode kompiliert nicht. Interessanterweise funktioniert es als Parameterwert in #enumParam
. Wie kann ich den Schnittstellentyp angeben, um das Klassenliteral von der Methode zurückzugeben?
Die Methode getEnum1
kompiliert nicht aus dem gleichen Grund wie diese:
Siehe? Nur weil der Typparameter E
eventuell eine Zeichenkette sein könnte, heißt das nicht, dass er kompatibel mit String
ist. Man könnte diese Funktion als Integer i = x.<Integer>foo();
bezeichnen, daher ist die Rückgabe eines Strings hier nicht sinnvoll.
getEnum1
ist ziemlich gleich. Der Type-Parameter E
kann als Typ E1
(sehr schlechte Benennung hier) gewählt werden, aber das bedeutet nicht, dass E1
immer mit E
kompatibel ist. Betrachte E2 e2 = x.<E2>getEnum1();
. Sie fragen sich vielleicht, warum der Compiler nicht nur einen Fehler meldet, wenn er versucht, ihn mit dem falschen Typparameter aufzurufen. Die Sache ist, E2
erfüllt die Typ-Constraints, also gibt es einfach keinen Grund, dort einen Fehler anzuzeigen.
Am einfachsten (und möglicherweise der einzige) Weg ist es, dort Generika loszuwerden:
%Vor% Wenn Sie den konkreten Typ E1
hier nicht anzeigen wollen, haben Sie kein Glück. Alles, was Sie tun können, ist, die allgemeinen Funktionalitäten zu einer Schnittstelle zu extrahieren und diesen Typ zurückzugeben.
Das Problem hierbei ist, dass Ihr Code niemals die richtige Instanz des Klassentyps zurückgibt, wenn der Kontext verwendet wird, der jedes Mal verwendet wird. ZB
%Vor% Der Compiler schlägt bei getEnum1
fehl, um einen verzögerten Laufzeitfehler zu verhindern, wenn jemand versucht, eine E2
gebundene Operation für das Objekt auszuführen, auf das von e2var verwiesen wird, was tatsächlich immer Class<E1>
ist.
Um eine Lösung vorzuschlagen, müssen Sie genauer festlegen, was dieser Klassensatz eigentlich beabsichtigt.
Im Gegensatz dazu ist es nicht überraschend, dass enumParam
funktioniert, da es kein passendes Klassenobjekt zurückgeben muss. Es ist jedoch offensichtlich, dass es aufgrund einer unendlichen Rekursion zu einem Stapelüberlauf kommen würde.