Erhalte den tatsächlichen Typ des generischen Arguments in der abstrakten Oberklasse

8

Ich habe eine Klasse wie:

%Vor%

Aber der Compiler sagt zu T.class; : Illegal class literal for the type parameter T .

Wie kann ich die Klasse von T bekommen?

    
t777 09.09.2013, 21:49
quelle

6 Antworten

16

Es ist definitiv möglich, es aus % co_de zu extrahieren % , weil es nicht während der Laufzeit definiert ist, sondern während der Kompilierungszeit von Class#getGenericSuperclass() .

Hier ist ein Kickoff-Beispiel, wie Sie den gewünschten generischen Supertyp im Konstruktor der abstrakten Klasse extrahieren können, indem Sie eine Hierarchie von Unterklassen berücksichtigen (zusammen mit einem realen Anwendungsfall für generische FooDao extends BaseDao<Foo> -Methoden ohne die muss den Typ explizit angeben):

%Vor%     
BalusC 10.09.2013, 01:11
quelle
7

Eigentlich ist das nicht so einfach wie es scheint. Es gibt ein Problem, wenn Sie eine Rich Type-Hierarchie haben und generische Parameter im Supertype erhalten möchten. Beispielsweise haben Sie möglicherweise die folgende Hierarchie:

%Vor%

Aufruf von getClass().getGenericSuperclass() in einer Instanz von MyDao gibt SpecialDao<TypeImpl, EntityImpl> zurück, aber wenn Sie es in BaseDao method aufrufen, wissen Sie nicht, wie tief die generische Hierarchie ist. Außerdem, soweit ich weiß, können Sie keinen generischen Supertyp eines Supertyps erhalten. Wenn Sie also getClass().getGenericSuperclass().getRawType().getGenericSuperclass() aufrufen (wobei einige Typumwandlung aus Gründen der Lesbarkeit weggelassen wurde), erhalten Sie BaseDao<E> (notice <E> anstelle von <T> ). Da getRawType() alle Typ-Variablen-Mappings vom Typ entfernt, beginnen wir mit den nicht zugeordneten Typ-Variablen X und E . Dann ordnet getGenericSuperclass() diese Typvariablen nur ihren Positionen in BaseDao zu.

Dieses Verhalten kann verwendet werden, damit wir beim Durchqueren der Typhierarchie die Zuordnung von Typvariablen zu ihren tatsächlichen Werten beibehalten. Wenn wir die Klasse treffen, die wir wollen, suchen wir einfach ihre Typparameter in der Karte nach. Hier ist der Code:

%Vor%     
Marcel Šebek 22.09.2014 12:21
quelle
6

Wenn das Spring-Framework verfügbar ist, können Sie Folgendes tun:

%Vor%     
eugene82 01.04.2015 08:44
quelle
5

Wenn Ihre Klasse abstrakt ist, können Sie Folgendes versuchen:

%Vor%

Dies funktioniert nur, wenn die Instanz eine direkte Unterklasse ist und der Typ der gewünschten Klasse der erste ist (siehe [0]).

Wenn Sie eine große Hierarchie von Daos haben, können Sie versuchen, das BaseDao rekursiv zu fidn und den parametrisierten Typ

zu erhalten

Sehen Sie ein Beispiel hier (siehe die Ausgabe unten)

Prost und Entschuldigung für mein schlechtes Englisch

    
Arturo Volpe 09.09.2013 22:52
quelle
1

Um dieses Problem auf sichere Weise zu lösen, fügen Sie einen Konstruktor hinzu, um die Klasse des Typs zu speichern. Beispiel in Ihrem Kontext:

%Vor%     
Farid 09.09.2013 22:02
quelle
0

Sie können TypeTools dafür auschecken:

%Vor%     
Jonathan 26.10.2013 02:15
quelle

Tags und Links

yii\base\ErrorException
Copied! Copy Stacktrace Search Stackoverflow Search Google Error

PHP Core Warningyii\base\ErrorException

PHP Startup: Unable to load dynamic library 'mongodb.so' (tried: /usr/lib64/php/modules/mongodb.so (/usr/lib64/php/modules/mongodb.so: cannot open shared object file: No such file or directory), /usr/lib64/php/modules/mongodb.so.so (/usr/lib64/php/modules/mongodb.so.so: cannot open shared object file: No such file or directory))

$_GET = [
    'id' => '322593',
    'url' => 'get-actual-type-of-generic-type-argument-on-abstract-superclass',
];

$_SESSION = [
    '__flash' => [],
];