Konstruktor vom generischen Typ aufrufen?

8

Ich versuche, mein eigenes Repository für meine Datenbank zu erstellen, also versuche ich etwas wie folgt:

%Vor%

Mit anderen Worten: Ich habe viele Klassen, die DatabaseObject erweitern, und ich möchte in der Lage sein, dynamisch einen Cursor für sie zu konstruieren.

Ich habe grundlegende Methoden in einem DatabaseObject definiert, wie zum Beispiel den Tabellennamen, String-Array von Spaltennamen usw., aber da ich statische Methoden nicht über die Schnittstelle (für Dinge wie Tabellenname) überschreiben kann, muss ich ein Leerzeichen instanziieren Objekt, damit ich den Tabellennamen mit einem Getter erhalten kann.

Ich bin mir jedoch nicht sicher, wie ich das umsetzen soll:

  1. somehowGetClassOfT() . Was auch immer T ist, ich möchte die Klasse dafür in die Cursor-Funktion übergeben.

  2. instantiateFromT(clazz) . Gegeben eine Klasse, rufen Sie den Konstruktor auf, damit ich Zugriff auf die Tabellen- / Projektions- / Sortierfelder dieses Objekts bekommen kann.

Oder ist das alles möglich, indem ich "Reflektion" verwende, von der ich schon gehört habe?

    
user7085962 29.10.2016, 19:36
quelle

1 Antwort

4

Generics werden zur Laufzeit nicht verdinglicht. Da die Information nicht vorhanden ist, haben Sie zwei Lösungen:

  • kann zur Kompilierungszeit gespeichert werden, indem ein privates Feld mit der Klasse
  • eingeführt wird
  • Sie können Reflektionen verwenden, um generische Typen zur Laufzeit von einer Instanz aufzulösen.

Hier ein Beispiel mit einem privaten Feld T und einem Konstruktor, ausgehend von Ihrem Code:

%Vor%

Hier Ihr DogRepository:

%Vor%

mit einem Hund, der DatabaseObject implementiert:

%Vor%

Um auf Ihren Kommentar zu antworten.

  

Die Zeile DogRepository (Class type), muss übergeben werden   die Klasse als Argument?

Nicht ist nicht nötig (sorry, ich habe deinen Kommentar gelesen)).
Und um weiter zu gehen, wie Sie vielleicht bemerken, sind die Konstrukteure für Betonbehälter der Kesselblechcode.
Wenn Sie Reflektion verwenden, um die Klasse hinter dem in DogRepository verwendeten generischen aufzulösen, müssen Sie keinen benutzerdefinierten Konstruktor mehr dafür definieren.

Um beispielsweise den im Repository verwendeten Typ abzurufen, führt Spring den Job mit einer eigenen Bibliothek aus, die JDK-Reflektionsmechanismen verwendet, etwa so:

%Vor%

Frühling hat seine Bibliothek, weil es viel Reflexion verwendet.
Aber in Ihrem Fall können Sie den Job auch ohne eine Lib, aber mit Ihrer eigenen Utility-Klasse ausführen. Hier ein Beispiel zum Auflösen des generischen Typs aus einer Repository-Instanz.

%Vor%

Mit Reflection zum Auflösen des effektiven generischen Typs in MyRepository constructor:

%Vor%

Die konkreten Repository-Klassen benötigen keinen benutzerdefinierten Konstruktor mehr:

%Vor%     
davidxxx 29.10.2016, 20:01
quelle