web-dev-qa-db-fra.com

Conversion de Java.lang.reflect.Type en classe <T> clazz

Comment puis-je convertir Java.lang.reflect.Type en Class<T> clazz?

Si j'ai une méthode en tant que suivante qui a un argument de Class<T>:

public void oneMethod(Class<T> clazz) {     
    //Impl
}

Puis une autre méthode qui a un argument de Java.lang.reflect.Type et appelle oneMethod(Class<T> clazz). Pour cela, je dois convertir Java.lang.reflect.Type type en Class<T>:

public void someMehtod(Java.lang.reflect.Type type) {
   // I want to pass type arg to other method converted in Class<T>
   otherMethod(¿How to convert Java.lang.reflect.Type to Class<T>?);
}

C'est possible?

11
Pau

Vous devez vous assurer que type est une instance de Class, puis lancez-la.

if (type instanceof Class) {
  @SuppressWarnings("unchecked")
  Class<?> clazz = (Class<?>) type;
  otherMethod(clazz);
}

Bien sûr, vous devez aussi gérer le cas où ce n'est pas une Class.

11
Andy Turner

Andy Turner répond correctement, mais si vous devez récupérer une classe à partir d'un paramètre de type, voici un exemple complet:

private static class MyClass extends ArrayList<Integer> {
}

public static void main(String[] args) {

    ParameterizedType arrayListWithParamType
            = (ParameterizedType) MyClass.class.getGenericSuperclass();

    Type integerType = arrayListWithParamType.getActualTypeArguments()[0];

    Class<?> integerClass = (Class<?>) integerType;

    System.out.println(integerClass == Integer.class);
}
0
xonya

Il serait étrange qu'une Type soit autre chose qu'une Class... Javadoc pour Type dit

Toutes les classes d'implémentation connues: Classe 

Donc, sauf si vous avez des bibliothèques spéciales qui utilisent des ClassTypes non, vous pouvez simplement lancer un cast - mais vous devez être prêt pour une possible ClassCastException. Attention: Java utilise une implémentation Type non documentée pour représenter les génériques, voir ci-dessous.

Vous pouvez le traiter explicitement ou non car il s'agit d'une exception non contrôlée:

Manière explicite:

try {
    Class<?> clazz = (Class<?>) type;
}
catch (ClassCastException ex) {
    // process exception
}

Manière implicite:

Class<?> clazz = (Class<?>) type;

mais la méthode actuelle pourrait jeter ...


EDIT par le commentaire de @Andy Turner: 

Attention: Type type = new ArrayList<String>().getClass().getGenericSuperclass(); donne quelque chose qui est un type mais pas une classe. Celui-ci est une ParameterizedType, vous pouvez donc utiliser la méthode getRawType() pour rechercher la classe réelle, mais d'autres peuvent exister.

0
Serge Ballesta

Si vous souhaitez utiliser une bibliothèque, vous pouvez utiliser com.google.guava:guava:12+:

Class<?> clazz = com.google.common.reflect.TypeToken.of(type).getRawType();

Sinon, vous pouvez aussi utiliser com.fasterxml.jackson.core:jackson-databind:2.8.x:

Class<?> clazz = com.fasterxml.jackson.databind.type.TypeFactory.rawClass(type);

Cela gère correctement tous les cas et vous obtiendrez la classe de votre type effacée.

0
Daniel Beer