如何找到Collection类型?

时间:2011-08-29 17:04:22

标签: java generics collections

我有两个变量

Collection<Service> services = new ArrayList<Service>();
Collection<Subscription> subscriptions = new ArrayList<Subscription>();

我有以下方法,我想知道如何才能找到“?”的值在这种方法中,或者我如何找到服务是否已通过或订阅是否已通过?

myMethod(Collection<?> myCollection) {

   if (myCollection is of type Service) {
      // process service
   }
   else if (myCollection is of type Subscription) {
      // process subscription
   }
}

感谢。

4 个答案:

答案 0 :(得分:4)

你做不到。 Java具有基于擦除的泛型,这意味着类型参数在运行时不可用。

如果你的收藏品不是空的,你当然可以在第一个元素上做instanceof

答案 1 :(得分:2)

在泛型方法中使用if-else构造会破坏泛型的目的。如果你需要知道在运行时传递的内容的类型,它实际上不应该是通用的,你应该为每种类型编写一个单独的方法。

答案 2 :(得分:2)

你不能(除了by using reflection),因为泛型类型参数在编译期间被删除。

我建议你重新考虑你的设计,而不是试图用泛型来解决它。从长远来看,将任意类型的集合传递到同一个方法中是一个问题的解决方案。

答案 3 :(得分:1)

没有Java方法可以做到这一点。类型擦除妨碍了。如果你需要这样做,那也可能是一个设计问题。 但是,如果你必须这样做,几乎可以做到这一点:

将变量更改为

Collection<Service> services = new ArrayList<Service>(){};
Collection<Subscription> subscriptions = new ArrayList<Subscription>(){};

注意()之后的{}。您没有创建ArrayList,而是从ArrayList继承的匿名类。并且类型擦除不适用于那里。因此,您可以通过执行类似

的操作来判断实际类型
private static Class<?> detectType(Collection<?> col) {
    return (Class<?>) ((ParameterizedType) col.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

该方法将返回实际的类。它确实有效,令人作呕。这取决于你。