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



我正在寻找一种方法来找出对象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,并从中获取原始类型。

然后您可以将rawtype转换为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
}

请注意,您不能根据参数化类型List<String>List<Integer>检查instanceof,因为这没有意义。它们在运行时都是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

相关内容

  • 没有找到相关文章

最新更新