Ich möchte einen generischen Typ definieren, dessen tatsächlicher Typparameter nur
sein kannLong
, Integer
, Float
, Double
) String
Ich kann die erste Anforderung mit einer solchen Definition erfüllen
%Vor%Aber ich kann mir nicht vorstellen, wie ich sie beide treffen soll. Ich vermute, dass dies nicht möglich ist, weil es bei der Definition eines formalen Typparameters keine Möglichkeit gibt, "oder" Semantiken anzugeben, obwohl Sie "und" Semantiken mit einer Definition wie
angeben können %Vor%Prost, Don
Java-Generics unterstützen keine Union-Typen (dieser Parameter kann A OR B sein).
Bei einer verwandten Notiz, die für einige von Interesse sein kann, unterstützt sie mehrere Schranken, wenn Sie mehrere Einschränkungen erzwingen möchten. Hier ein Beispiel aus dem JDK, das im Java Generik-Tutorial erwähnt wird:
%Vor%Sie können Factory-Methoden für alle unterstützten Typen verwenden und den Konstruktor privat / geschützt machen. Sie müssen den generischen Typ trotzdem im Konstruktor korrigieren, so dass es Sinn macht, also könnten Sie es wahrscheinlich so codieren:
%Vor%Oder wenn Sie den Konstruktorparameter nicht möchten, etwa so: öffentliche Abschlussklasse MyClass { Öffentliche statische MyClass newIntegerInstance () { return new MeineKlasse (); } // ... }
Wie erickson sagte, kann die allgemeine Implementierung nur auf Object angewiesen sein. Die einzige Einschränkung ist, dass Sie neben den Primitiven und String auch andere Implementierungen für andere Typen erstellen können.
Während Generika hier nicht funktionieren, wird ein Basistyp mit abgeleiteten Typen für Number
und String
verwendet. Da ein generischer Typ sowieso in Object
gelöscht würde, kann jede Funktionalität, die Sie dort angegeben hätten, in eine abstrakte Basisklasse aufgenommen werden. Sie benötigen wahrscheinlich nur einen typspezifischen Accessor für die Unterklasse, um den Wert zu erhalten.
Seien Sie auch vorsichtig mit der Klasse Number
. Es ist nicht darauf beschränkt, die primitiven Typen einzubetten, da jeder sie erweitern kann, z. B. BigInteger
.
Interessante Frage, es hat mich ein bisschen verblüfft. Dies ist jedoch scheinbar unmöglich. Ich habe mehrere verschiedene Hacks ausprobiert, keiner funktioniert wirklich.
Vielleicht könntest du Folgendes tun:
MyClass<T>
zu einer Paket-Standardklasse, unsichtbar für andere Komponenten oder zumindest für Paket-Standard-Ctors, so dass sie außerhalb des Pakets nicht erweitert oder instanziiert werden kann. MyClass<T>
: %Vor%
Auf diese Weise werden alle Unterklassen von MyClass auf diejenigen beschränkt, die mit einer Number-Unterklasse oder String parametrisiert sind.