我有两个变量
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
}
}
感谢。
答案 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];
}
该方法将返回实际的类。它确实有效,令人作呕。这取决于你。