我正在寻找一种方法来找出对象 x
是一个实例
属于泛型。例如List<String>
.
受 Super-Type-Token 习惯用法的启发,我可以检索 java.lang.reflect.Type
在运行时使用以下代码
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class Test {
public static void main(String[] args) {
TypeReference<List<String>> ref = new TypeReference<List<String>>() {};
System.out.println(ref.getType());
System.out.println(ref.getType().getClass());
}
abstract static class TypeReference<T> {
private final Type type;
protected TypeReference() {
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
type = superclass.getActualTypeArguments()[0];
}
public Type getType() {
return type;
}
}
}
输出是
java.util.List<java.lang.String>
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
我如何使用这些信息进行动态转换或类型检查?
背景是我目前正在编写异构类型安全容器库,并希望添加对泛型类型的支持 https://bitbucket.org/mbeyene/jam
最佳答案
您必须注意到您正在使用参数化类型作为 TypeReference<T>
的类型参数实例。所以你需要将它转换为 ParameterizedType
在调用端,并从中获取原始类型。
然后您可以将该原始类型转换为 Class<?>
输入并使用 Class#isInstance()
方法:
public static void main(String[] args) {
TypeReference<List<String>> ref = new TypeReference<List<String>>() {};
List<String> list = new ArrayList<String>();
Type rawType = ((ParameterizedType)ref.getType()).getRawType();
boolean listIsInstanceOfRawType = ((Class<?>)(rawType)).isInstance(list));
System.out.println(listIsInstanceOfRawType); // true
}
请注意,您无法根据参数化类型检查 instanceof - List<String>
或 List<Integer>
,因为那没有意义。他们两个都不过是List
在运行时。我的意思是:
List<String> list = new ArrayList<String>();
System.out.println(list instanceof List<String>); // Won't compile
System.out.println(list instanceof List); // You've to do this.
// The reason is, this is true
System.out.println(new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass()); // true
关于java - 使用 java.lang.reflect.Type 检查实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22332435/