本文介绍了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
- 我是否正确理解这是由于Type Erasure的影响,并且它应该被解释为未知,因为 E 是类型参数名称? li>
- 这让我觉得很奇怪,因为我不得不专门解释名称E(并且我认为S,U等等,如果更多的话)。如果我有一个班级E怎么办?此外,方法名称为get_ Actual _TypeArguments。鉴于类型参数非常像变量一样充当占位符,我发现一个方法应该返回变量的名称非常奇怪。我在这里丢失了什么?
-
另外,我不清楚为什么我可以将超类转换为 ParameterizedType ,但不是类本身。尝试将 li.getClass()的结果强制转换为 ParameterizedType 会产生以下编译时错误:
required:ParameterizedType
found:Class
其中CAP#1是一个新的类型变量:
CAP#1 extends从捕获的? extends List
我见过这个,但它并没有启发我。
所有的泛型类实例共享相同的运行时类:
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返回源代码中声明的实际类型参数,但这些类型参数可能包含在别处声明的类型变量。
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
- 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?
- 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?
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: ParameterizedTypefound: 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.
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 ::在运行时获取参数化类型名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!