Java获取通用类型的集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19253121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java get generic type of collection
提问by Gumba
My project include reflection and i'm currently handling with generic types. I've managed to get the generic type from a List(java.util.List) with:
我的项目包括反射,我目前正在处理泛型类型。我已经设法从 List(java.util.List) 获取泛型类型:
if(originalField.getGenericType() instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType) originalField.getGenericType();
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
}
I also have a Collection<String>
and it turns out that Collection can NOTbe cast to ParameterizedType.
我也有一个Collection<String>
,结果表明不能将Collection 转换为 ParameterizedType。
Someone have an idea how to get the String (or whatever type that will be) out of the collection?
有人知道如何从集合中获取字符串(或任何类型)?
I've been reading about java erasure so i'm aware of that, but after getting the generic out of the List, i thought that maybe someone knows another 'trick'.
我一直在阅读有关 Java 擦除的内容,所以我知道这一点,但是在从列表中取出泛型之后,我想也许有人知道另一个“技巧”。
Thanks.
谢谢。
EDITED: I'm iterating over all of the fields of the class with:
已编辑:我正在使用以下内容迭代该类的所有字段:
for (Field originalField : someClass.getDeclaredFields())
And then when i'm facing some List<String>
Field, with the above code i getting the String
as the subClass variable.
然后当我面对某个List<String>
Field 时,使用上面的代码,我将其String
作为 subClass 变量。
采纳答案by Rohit Jain
Your approach is fine. It should work for both List<String>
and Collection<String>
. For example see this sample code:
你的方法没问题。它应该适用于List<String>
和Collection<String>
。例如,请参阅此示例代码:
public class Demo {
List<String> list = new ArrayList<>();
Collection<String> coll = new ArrayList<>();
public static void main(String args[]){
Class<Demo> clazz = Demo.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field: fields) {
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType)type;
Type[] arr = pType.getActualTypeArguments();
for (Type tp: arr) {
Class<?> clzz = (Class<?>)tp;
System.out.println(clzz.getName());
}
}
}
}
}
this prints out:
这打印出来:
java.lang.String
java.lang.String
回答by Giulio Franco
As far as I know, Java fully erases the type, so the compiled code has no traces of the value you assigned to parameter types. All the parametric types are translated to concrete types, with type castings and things like that
据我所知,Java 完全擦除了类型,因此编译后的代码没有您分配给参数类型的值的痕迹。所有参数类型都被转换为具体类型,类型转换和类似的东西
In the code I've seen so far, when a class need to know the value of its generic type, it forces an object of that type (or the class) to be passed as a parameter. Something like:
在我目前看到的代码中,当一个类需要知道其泛型类型的值时,它会强制将该类型(或类)的对象作为参数传递。就像是:
class A<T> {
private final Class<T> parameterType;
public A(Class<T> parCls) {
parameterType = parCls;
}
public A(T tObj) {
parameterType = tObj.getClass();
}
}
回答by Jonathan
You'll need to resolve the ParameterizedType using whatever type it was defined on. For example, using TypeTools:
您需要使用定义的任何类型来解析 ParameterizedType。例如,使用TypeTools:
class Foo<T> {
public T bar;
}
class StringFoo extends Foo<String> {}
Type barType = Foo.class.getDeclaredField("bar").getGenericType();
Class<?> t = TypeResolver.resolveRawClass(barType, StringFoo.class);
assert t == String.class;
Here the value of T
was defined in StringFoo, so we can use TypeResolver
to resolve the raw class for our field's type using StringFoo
这里的值T
是在 StringFoo 中定义的,因此我们可以使用以下TypeResolver
方法解析字段类型的原始类StringFoo