在运行时指定泛型集合类型参数(Java反射) [英] Specifying generic collection type param at runtime (Java Reflection)

查看:690
本文介绍了在运行时指定泛型集合类型参数(Java反射)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在运行时使用反射来获取集合的泛型类型。

I'd like to get the generic type of a collection, using reflection, at runtime.

代码(JAVA):

Field collectionObject = object.getClass().getDeclaredField(
    collectionField.getName());
//here I compare to see if a collection
if (Collection.class.isAssignableFrom(collectionObject.getType())) {
   // here I have to use the generic type of the collection 
   // to see if it's from a specific type - in this case Persistable
   if (Persistable.class.isAssignableFrom(GENERIC_TYPE_COLLECTION.class)) {
   }
}

有没有办法在运行时在java中获取集合的泛型类型?在我的情况下,我需要集合的通用类型的.class。

Is there a way of getting the generic type of the collection in java at runtime? In my case I need the .class of the collection's generic type.

提前致谢!

推荐答案

类型擦除表示在执行时不存在关于对象的泛型类型的信息。

Type erasure means that information about the generic type of an object simply isn't present at execution time.

(链接指向Angelika Langer Java Generics FAQ 的相关部分,该部分应该是回答几乎所有关于Java泛型的问题:)

(The link is to the relevant section of Angelika Langer's Java Generics FAQ which should answer virtually every question you could possibly ask about Java generics :)

但是,你对对象的类型并不感兴趣 - 你对这种类型感兴趣一个字段。我误解了这个问题,虽然答案已被接受,但我希望现在通过修复来弥补:)

However, you're not really interested in the type of an object - you're interested in the type of a field. I misread the question, and although the answer has been accepted I hope to make amends by fixing it now :)

如果字段本身不使用类型参数,可以办到。例如:

If the field doesn't use a type parameter itself, it can be done. For example:

import java.lang.reflect.*;
import java.util.*;

public class Test
{
    public List<String> names;

    public static void main(String [] args)
        throws Exception // Just for simplicity!
    {
        Field field = Test.class.getDeclaredField("names");

        ParameterizedType type = (ParameterizedType) field.getGenericType();

        // List
        System.out.println(type.getRawType());

        // Just String in this case
        for (Type typeArgument : type.getActualTypeArguments())
        {
            System.out.println("  " + typeArgument);
        }
    }
}

如果该字段位于class T ,字段为 List< T> 然后你必须知道实例的类型参数为了知道集合的类型参数。

If the field were in a class T with the field being List<T> then you'd have to know the type argument for the instance in order to know the type argument for the collection.

将它转换为你需要的代码有点棘手 - 你真的需要知道集合点的类型参数类。例如,如果有人声明:

Translating this into your required code is somewhat tricky though - you really need to know the type argument at the point of the collection class. For instance, if someone declared:

public class StringCollection implements Collection<String>

然后有一个 StringCollection 类型的字段,该字段本身不会有任何类型参数。然后,您需要递归检查 getGenericSuperType getGenericInterfaces ,直到找到所需内容。

and then had a field of type StringCollection, that field itself wouldn't have any type arguments. You'd then need to check getGenericSuperType and getGenericInterfaces recursively until you found what you wanted.

尽管有可能,但要做到这一点真的不容易。如果我是你,我会尝试改变你的设计,这样你就不需要了。

It's really not going to be easy to do that, even though it's possible. If I were you I'd try to change your design so that you don't need this.

这篇关于在运行时指定泛型集合类型参数(Java反射)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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