In Java ist es möglich, eine typsichere Zuordnung von Klassen zu Instanzen ihrer Klasse zu erstellen?

8

Ich möchte eine Map erstellen, die eine Klasse als Schlüssel verwendet, um eine Instanz dieser Klasse zurückzugeben. Etwas wie:

%Vor%

Ist das möglich? Ich habe das Gefühl, dass es nicht so ist, weil ich nicht angeben kann, dass T eher ein generischer Typ als eine Klasse namens "T" sein soll. Es fühlt sich irgendwie wie "Generika höherer Ordnung" an.

BEARBEITEN: Ich weiß, dass ich versuchen könnte, Map zu erweitern und meinen eigenen Wrapper usw. zu implementieren, aber ich frage speziell danach, ob ich nur die generische Java-Unterstützung verwenden soll. Ich bin mehr an der Idee interessiert als an diesem speziellen Fall.

BEARBEITEN 2: Wie unten ausgeführt, ist dies ein Duplikat (oder genauer gesagt ein Unterfall) der Frage: Java-Map mit Werten, die durch den key type-Parameter begrenzt sind . Hätte ich Formulierungen gefunden, die so eloquent sind, hätte ich diese Antwort wahrscheinlich gefunden und nicht gepostet.

    
ArtB 22.07.2011, 19:25
quelle

6 Antworten

3

Wie ich Sie verstehe, möchten Sie sagen, dass Sie nach dem Erstellen dieser Map etwas mit ...

füllen möchten %Vor%

usw. Richtig?

In diesem Fall denke ich, die Antwort ist nein, das kann man nicht mit Generika machen. Generics sagen, dass Sie für eine bestimmte Instanz der Klasse - in diesem Fall die Karte - die Typen angeben, die anwendbar sind. Wenn Sie also new HashMap<String,Integer>; sagen, sagen Sie, dass alle Operationen mit dieser Map einen Schlüssel verwenden, der eine Zeichenfolge und einen Wert darstellt, der eine Ganzzahl ist. Aber das ist nicht das, was Sie in diesem Fall tun möchten. Sie möchten in der Lage sein, beliebige Objekte in die Klasse einzufügen und dann die zulässigen Typen für den Schlüssel basierend auf dem Objekttyp einzuschränken. So funktionieren Generika nicht. Sie sind keine Beziehung zueinander, sie sind eine Konstante für jede gegebene Instanz.

Sie könnten natürlich eine solche Karte als new HashMap<Class,Object>; erstellen. Dies würde die Klasse nicht zur Klasse des entsprechenden Objekts zwingen, aber es würde Ihnen erlauben, solche Werte einzugeben.

Abgesehen davon denke ich, dass Sie einen Wrapper brauchen würden. Sollte ich darauf hinweisen, dass der put des Wrappers nur einen Parameter benötigt, da er vermutlich die Klasse des Parameters bestimmen könnte, indem er getClass() ausführt, müsste man das nicht sagen?

    
Jay 22.07.2011, 21:03
quelle
11

Sie meinen so etwas?

%Vor%

Siehe als Referenz: Java-Map mit Werten, die durch Schlüssel begrenzt sind Geben Sie den Parameter

ein     
fyr 22.07.2011 19:32
quelle
1

In Ihrem Beispiel müsste T für jeden Schlüssel / Wert unterschiedlich sein, während bei% generics T für jeden Schlüssel / Wert gleich sein muss. Also nein, das ist mit Generika nicht möglich. (aber natürlich ist die Implementierung bei Casting und / oder Nicht-Verwendung von Generika durchaus möglich)

    
Kirk Woll 22.07.2011 19:31
quelle
0

Der Punkt von Map<T, U> besteht darin, T's auf Us abzubilden. T und U können jede Klasse sein (keine Platzhalter vorausgesetzt), aber sobald sie bestimmt sind, können sie sich nicht ändern. In Ihrem Fall möchten Sie ein Mapping, das je nach verwendetem Schlüssel eine andere Klasse zurückgibt, was natürlich anders ist.

Der übliche Weg, dies zu tun, ist, einfach U Object zu machen, da du weitermachen kannst, um es auf alles zu übertragen, was du brauchst. Aber das bricht natürlich die Typensicherheit, die Generika liefern sollen.

Kurz gesagt, ich denke nicht, dass dies möglich wäre, ohne eine Art Wrapper zu schreiben.

    
dlev 22.07.2011 19:32
quelle
0

T muss bei der Erstellung einer Instanz auf einen bestimmten Typ festgelegt werden, sodass Sie der Karte mit der Methode put keine anderen Typen hinzufügen können. Bei generischen Methoden hingegen werden die Argumente ihres Typs beim Aufruf festgelegt, damit Sie tun können, was Sie wollen.

Guava hat eine ClassToInstanceMap Geben Sie generische Methoden ein, um Instanzen in der Map sicher zu platzieren und wieder zu entfernen.

    
ColinD 22.07.2011 19:49
quelle
0

JsonObject ist möglicherweise eine Option. Sie können den Wert des Json-Objekts beliebig setzen. Was Sie brauchen, ist das Paket org.json.JSONObject. Allerdings können Sie foreach möglicherweise nicht mit JSONObject verwenden, aber es gibt alternative Methoden So durchlaufen Sie i JSONObject?

    
Cong Zhao 22.10.2013 23:17
quelle

Tags und Links