使用java.lang.reflect.type检查示例

6ovsh4lw  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(416)

我在想办法找出 x 是泛型类型的示例。例如 List<String> .
受超级类型标记成语的启发,我可以检索 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

k7fdbhmy

k7fdbhmy1#

您必须注意,您正在使用参数化类型作为的类型参数 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

相关问题