Java ::在运行时获取参数化类型名称 [英] Java :: obtaining parameterized type names at runtime

查看:299
本文介绍了Java ::在运行时获取参数化类型名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码:

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


$ / code $ / pre

产生:

 参数化类型1是:E 




  1. 我是否正确理解这是由于Type Erasure的影响,并且它应该被解释为未知,因为 E 是类型参数名称? li>
  2. 这让我觉得很奇怪,因为我不得不专门解释名称E(并且我认为S,U等等,如果更多的话)。如果我有一个班级E怎么办?此外,方法名称为get_ Actual _TypeArguments。鉴于类型参数非常像变量一样充当占位符,我发现一个方法应该返回变量的名称非常奇怪。我在这里丢失了什么?

  3. 另外,我不清楚为什么我可以将超类转换为 ParameterizedType ,但不是类本身。尝试将 li.getClass()的结果强制转换为 ParameterizedType 会产生以下编译时错误:

    required:ParameterizedType
    found:Class
    其中CAP#1是一个新的类型变量:
    CAP#1 extends从捕获的? extends List


我见过这个相关的SO帖子,但它并没有启发我。

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

  new ArrayList< Integer>()。getClass )==新的ArrayList< String>()。getClass()

换句话说,跟踪用于实例化泛型类的实际类型参数。但是,它知道源代码中声明的类型,这就是getGenericSuperclass()和朋友返回的内容。所以如果你有一个类:

  class Environment扩展HashMap< String,Object> {b 
$ b}

表达式

  new Environment()。getClass()。getGenericSuperclass()

返回

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

相反,如果您声明

  class Environment< E>扩展HashMap< String,E> {
}

相同的表达式返回

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

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


另外,我不清楚为什么我可以将超类转换为 ParameterizedType 而不是类本身。

A ParametrizedType object表示编译时类型使用非空的类型参数列表,一个 Class 对象的运行时类型(它没有任何类型参数)。因此, Class 不是 ParametrizedType


The following code:

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);
    }
}

produces:

parameterized type 1 is: E

  1. Do I understand correctly that this is because of the effects of Type Erasure and that it should be interpreted as "unknown", given that E is the type parameter name?
  2. It strikes me as odd that I somehow have to interpret the name "E" (and I suppose "S", "U", etc. if more exist) specially. What if I have a class "E"? Moreover the method name is get_Actual_TypeArguments. Given that type parameters serve as placeholders much like variables I find it very odd that a method should return the name of the variable. Am I missing something here?
  3. Also, it's not clear to me why I can cast the superclass to ParameterizedType but not the class itself. Trying to cast the result of li.getClass() as a ParameterizedType yields the following compile time error:

    required: ParameterizedType found: Class where CAP#1 is a fresh type-variable: CAP#1 extends List from capture of ? extends List

I've seen this relevant SO post but it hasn't enlightened me.

解决方案

All instances of a generic class share the same runtime class:

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

Put differently, the runtime does not track the actual type arguments used to instantiate a generic class. However, it does know the types declared in the source code, and that's what getGenericSuperclass() and friends return. So if you have a class:

class Environment extends HashMap<String, Object> {

}

The expression

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

returns

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

In contrast, if you declare

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

the same expression returns

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

So yes, getGenericSuperclass returns the actual type parameters as declared in the source code, but those type parameters may contain type variables declared elsewhere.

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

A ParametrizedType object represents a compile time type with a non-empty list of type arguments, a Class object a runtime type (which doesn't have any type arguments). Therefore, a Class is not a ParametrizedType.

这篇关于Java ::在运行时获取参数化类型名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆