Java::在运行时获取参数化类型名称

标签 java generics reflection type-erasure

以下代码:

public static void main(String args[]) throws NoSuchFieldException {
    List<Integer> li = new ArrayList<Integer>();
    ParameterizedType apType = (ParameterizedType) li.getClass().getGenericSuperclass();
    Type[] typeArguments = apType.getActualTypeArguments();
    int _i = 0;
    for (Type type : typeArguments) {
        System.out.format("parameterized type %d is: %s", ++_i, type);
    }
}

产生:

parameterized type 1 is: E
  1. 我是否正确理解这是由于类型删除的影响,并且考虑到 E 是类型参数名称,因此应将其解释为“未知”?
  2. 令我感到奇怪的是,我必须以某种方式特殊解释名称“E”(我想“S”、“U”等,如果存在更多的话)。如果我有“E”级怎么办?此外,方法名称是 get_Actual_TypeArguments。鉴于类型参数充当占位符,就像变量一样,我发现方法应该返回变量的名称,这很奇怪。我在这里错过了什么吗?
  3. 此外,我不清楚为什么我可以将父类(super class)转换为 ParameterizedType 而不是类本身。尝试将 li.getClass() 的结果转换为 ParameterizedType 会产生以下编译时错误:

    必需:参数化类型 发现:类 其中 CAP#1 是一个新的类型变量: CAP#1 从捕获 ? 扩展列表扩展列表

我见过这个relevant SO post但它并没有启发我。

最佳答案

泛型类的所有实例共享相同的运行时类:

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass()

换句话讲,运行时不会跟踪用于实例化泛型类的实际类型参数。但是,它确实知道源代码中声明的类型,这就是 getGenericSuperclass() 和 friend 返回的内容。因此,如果您有一个类:

class Environment extends HashMap<String, Object> {

}

表达式

new Environment().getClass().getGenericSuperclass()

返回

java.util.HashMap<java.lang.String, java.lang.Object>

相反,如果您声明

class Environment<E> extends HashMap<String, E> {
}

返回相同的表达式

java.util.HashMap<java.lang.String, E>

所以,是的,getGenericSuperclass 返回源代码中声明的实际类型参数,但这些类型参数可能包含在其他地方声明的类型变量。

Also, it's not clear to me why I can cast the superclass to ParameterizedType but not the class itself.

ParametrizedType 对象表示具有非空类型参数列表的编译时类型,Class 对象表示运行时类型(没有任何类型参数) )。因此,Class 不是 ParametrizedType

关于Java::在运行时获取参数化类型名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16886593/

相关文章:

Java 正则表达式空格匹配 $ 和 * ??

asp.net - MVC 通用 ViewModel

C# - 如何使用反射调用参数数量可变的静态方法

java - 将字符串解析为不带语言环境的日期

java - 如何创建获取两个参数的方法 - 流和整数

java - Spring MVC MappingJackson2JsonView 集合元素重复

java - 将比较器与泛型一起使用

TypeScript Omit 和 keyof

reflection - 在方法调用中找到真正的调用者

java - 如何访问通用对象的类型?