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
?
Viele Menschen kennen diesen Trick nicht! Eigentlich habe ich ihn erst heute entdeckt! Er funktioniert wie ein Traum! Schaut euch einfach dieses Beispiel an:
public static void main(String[] args) {
Date d=new Date(); //Or anything you want!
printMethods(d);
}
public static <T> void printMethods(T t){
Class<T> clazz= (Class<T>) t.getClass(); // There you go!
for ( Method m : clazz.getMethods()){
System.out.println( m.getName() );
}
}
Wie bereits in anderen Antworten erläutert, ist die Verwendung dieser ParameterizedType
Ansatz, müssen Sie die Klasse zu erweitern, aber das scheint wie zusätzliche Arbeit, um eine ganz neue Klasse, die es erweitert zu machen ...
Wenn man also die Klasse abstrakt macht, ist man gezwungen, sie zu erweitern, wodurch die Anforderung der Unterklassifizierung erfüllt wird. (unter Verwendung von Lomboks @Getter).
@Getter
public abstract class ConfigurationDefinition<T> {
private Class<T> type;
...
public ConfigurationDefinition(...) {
this.type = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
...
}
}
Nun soll sie erweitert werden, ohne eine neue Klasse zu definieren. (Beachten Sie die {} am Ende... erweitert, aber überschreibt nichts - es sei denn, Sie wollen es).
private ConfigurationDefinition<String> myConfigA = new ConfigurationDefinition<String>(...){};
private ConfigurationDefinition<File> myConfigB = new ConfigurationDefinition<File>(...){};
...
Class stringType = myConfigA.getType();
Class fileType = myConfigB.getType();
Wenn Sie eine Klasse/Schnittstelle erweitern oder implementieren, die Generics verwendet, können Sie den generischen Typ der übergeordneten Klasse/Schnittstelle abrufen, ohne eine vorhandene Klasse/Schnittstelle überhaupt zu ändern.
Dafür gibt es drei Möglichkeiten,
Fall 1 Wenn Ihre Klasse eine Klasse erweitert, die Generics verwendet
public class TestGenerics {
public static void main(String[] args) {
Type type = TestMySuperGenericType.class.getGenericSuperclass();
Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
for(Type gType : gTypes){
System.out.println("Generic type:"+gType.toString());
}
}
}
class GenericClass<T> {
public void print(T obj){};
}
class TestMySuperGenericType extends GenericClass<Integer> {
}
Fall 2 Wenn Ihre Klasse eine Schnittstelle implementiert, die Generics verwendet
public class TestGenerics {
public static void main(String[] args) {
Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
for(Type type : interfaces){
Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
for(Type gType : gTypes){
System.out.println("Generic type:"+gType.toString());
}
}
}
}
interface GenericClass<T> {
public void print(T obj);
}
class TestMySuperGenericType implements GenericClass<Integer> {
public void print(Integer obj){}
}
Fall 3 Wenn Ihre Schnittstelle eine Schnittstelle erweitert, die Generics verwendet
public class TestGenerics {
public static void main(String[] args) {
Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
for(Type type : interfaces){
Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
for(Type gType : gTypes){
System.out.println("Generic type:"+gType.toString());
}
}
}
}
interface GenericClass<T> {
public void print(T obj);
}
interface TestMySuperGenericType extends GenericClass<Integer> {
}
Diese Frage ist alt, aber jetzt ist es das Beste, Google zu benutzen Gson
.
Ein Beispiel für eine kundenspezifische Anpassung viewModel
.
Class<CustomViewModel<String>> clazz = new GenericClass<CustomViewModel<String>>().getRawType();
CustomViewModel<String> viewModel = viewModelProvider.get(clazz);
Generische Typklasse
class GenericClass<T>(private val rawType: Class<*>) {
constructor():this(`$Gson$Types`.getRawType(object : TypeToken<T>() {}.getType()))
fun getRawType(): Class<T> {
return rawType as Class<T>
}
}
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.