Ich habe eine generische Klasse, Foo<T>
. Bei einer Methode der Foo
Ich möchte die Klasseninstanz des Typs T
aber ich kann einfach nicht anrufen T.class
.
Was ist der bevorzugte Weg, um das Problem zu umgehen? T.class
?
Ich habe eine generische Klasse, Foo<T>
. Bei einer Methode der Foo
Ich möchte die Klasseninstanz des Typs T
aber ich kann einfach nicht anrufen T.class
.
Was ist der bevorzugte Weg, um das Problem zu umgehen? T.class
?
Stellen Sie sich vor, Sie haben eine abstrakte Oberklasse, die generisch ist:
public abstract class Foo<? extends T> {}
Und dann haben Sie eine zweite Klasse, die Foo mit einer generischen Bar erweitert, die T erweitert:
public class Second extends Foo<Bar> {}
Sie können die Klasse Bar.class
in der Klasse Foo durch Auswahl der Option Type
(aus der Antwort von bert bruynooghe) und deren Ableitung durch Class
Instanz:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);
Es ist zu beachten, dass dieser Vorgang nicht ideal ist, so dass es eine gute Idee ist, den berechneten Wert zwischenzuspeichern, um mehrere Berechnungen zu vermeiden. Eine der typischen Verwendungen ist in der generischen DAO-Implementierung.
Die endgültige Umsetzung:
public abstract class Foo<T> {
private Class<T> inferedClass;
public Class<T> getGenericClass(){
if(inferedClass == null){
Type mySuperclass = getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
String className = tType.toString().split(" ")[1];
inferedClass = Class.forName(className);
}
return inferedClass;
}
}
Der zurückgegebene Wert ist Bar.class, wenn er von der Klasse Foo in einer anderen Funktion oder von der Klasse Bar aufgerufen wird.
Ich hatte dieses Problem in einer abstrakten generischen Klasse. In diesem speziellen Fall ist die Lösung einfacher:
abstract class Foo<T> {
abstract Class<T> getTClass();
//...
}
und später auf die abgeleitete Klasse:
class Bar extends Foo<Whatever> {
@Override
Class<T> getTClass() {
return Whatever.class;
}
}
Im Folgenden stelle ich meine (hässliche, aber effektive) Lösung für dieses Problem vor:
import java.lang.reflect.TypeVariable;
public static <T> Class<T> getGenericClass() {
__<T> instance = new __<T>();
TypeVariable<?>[] parameters = instance.getClass().getTypeParameters();
return (Class<T>)parameters[0].getClass();
}
// Generic helper class which (only) provides type information. This avoids the
// usage of a local variable of type T, which would have to be initialized.
private final class __<T> {
private __() { }
}
Das geht nicht, weil die Schrift gelöscht werden muss. Siehe auch Stack Overflow Frage Java Generics - Typenlöschung - wann und was passiert? .
Ein besserer Weg als die von den anderen vorgeschlagene Klasse ist die Übergabe eines Objekts, das das tun kann, was Sie mit der Klasse getan hätten, z. B. eine neue Instanz erstellen.
interface Factory<T> {
T apply();
}
<T> void List<T> make10(Factory<T> factory) {
List<T> result = new ArrayList<T>();
for (int a = 0; a < 10; a++)
result.add(factory.apply());
return result;
}
class FooFactory<T> implements Factory<Foo<T>> {
public Foo<T> apply() {
return new Foo<T>();
}
}
List<Foo<Integer>> foos = make10(new FooFactory<Integer>());
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
2 Stimmen
Versuchen Sie, diese Frage zu beantworten, ich denke, es ist ähnlich. stackoverflow.com/questions/1942644/
3 Stimmen
Mögliche Duplikate von Generischen Typ einer Klasse zur Laufzeit abrufen
1 Stimmen
Mögliche Duplikate von Instanziierung einer generischen Klasse in Java
2 Stimmen
import com.fasterxml.jackson.core.type.TypeReference;
new TypeReference<T>(){}
0 Stimmen
Ja, wie der obige Kommentar andeutet, habe ich das Problem durch die Bereitstellung von
new TypeReference<Foo<Bar>>() {}
als Parameter für meine deserialisierte Modelllesemethode.