java - 使用 java.lang.reflect.Type 检查实例

标签 java generics reflection

我正在寻找一种方法来找出对象 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/

相关文章:

java - 当单元格包含空值时从excel中获取数据

generics - f# 可区分联合泛型

Java泛型。为什么要编译?

java - 由于某些中间构造函数,类型 MySuperClass<B> 的封闭实例不可用

java - 从注释处理器中的注释对象获取类字段

java - 函数方法

java - Spring Boot 事件监听器不接收事件

java - 反射类仅初始化一次

c# - Type.IsPublic 和 Type.IsVisible 有什么区别

java - 使用java检查模糊图像