Suppose I have some method that accepts a List<?>
public void method(List<?> list) {
// some logic
}
How can I get the element type in runtime? Is it possible?
I found these suggestions (here on SO):
((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]
(doesn't work,List
is an interface and doesn't have a superclass)
// ChatGPT's work
public class App {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();
Type stringType = getListElementType(stringList);
Type integerType = getListElementType(integerList);
System.out.println("String List Element Type: " + stringType.getTypeName());
System.out.println("Integer List Element Type: " + integerType.getTypeName());
}
private static Type getListElementType(List<?> list) {
Type genericType = list.getClass().getGenericSuperclass();
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
return parameterizedType.getActualTypeArguments()[0];
}
throw new IllegalArgumentException("Unable to determine list element type.");
}
}
Console output:
String List Element Type: E
Integer List Element Type: E
- Storing a corresponding class as a field during creation of a generic class instance (doesn't work,
List
is read-only, and it can't have any instance fields anyway since it's an interface)
/*
from jqno's answer to "How can I learn actual type argument of an generic class?"
Henning in his answer to "Get generic type of class at runtime" suggested a similar trick
*/
class ParameterizedClass<T> {
private Class<T> type;
/** Factory method */
public static <T> ParameterizedClass<T> of(Class<T> type) {
return new ParameterizedClass<T>(type);
}
/** Private constructor; use the factory method instead */
private ParameterizedClass(Class<T> type) {
this.type = type;
}
// Do something useful with type
}
- The TypeTools library. I still need some supertype
The TypeResolver class provides some of the following methods:
Type reify(Type type, Class<S> context)
Returns a fully reified type using type variable information from the context.
Type reify(Type genericType)
Returns a fully reified genericType using information from the generic declaration.
Class<?>[] resolveRawArguments(Class<T> type, Class<S> subType)
Resolves the raw arguments for a type using type variable information from a subType.
Class<?> resolveRawArgument(Class<T> type, Class<S> subType)
Resolves the raw argument for a type using type variable information from a subType.
Type resolveGenericType(Class<?> type, Type subType)
Resolves the generic type using type variable information from a subType.
Class<?> resolveRawClass(Type genericType, Class<?> subType)
Resolves the raw class for a genericType using type variable information from a subType.
Aucun commentaire:
Enregistrer un commentaire