883 Stimmen

Wie erhalte ich eine Klasseninstanz des generischen Typs T?

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 ?

2 Stimmen

Versuchen Sie, diese Frage zu beantworten, ich denke, es ist ähnlich. stackoverflow.com/questions/1942644/

3 Stimmen

1 Stimmen

2voto

Omid.N Punkte 794

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() );
    }
}

2voto

Riaan Schutte Punkte 470

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();

2voto

Abel ANEIROS Punkte 5350
   public <T> T yourMethodSignature(Class<T> type) {

        // get some object and check the type match the given type
        Object result = ...            

        if (type.isAssignableFrom(result.getClass())) {
            return (T)result;
        } else {
            // handle the error
        }
   }

1voto

Anil Agrawal Punkte 2190

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> {
}

0voto

Vahe Gharibyan Punkte 4107

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.com

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.

Powered by:

X