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?
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
.
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);
}
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 Class
Type
s 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.
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.