[英]Java generic method optional type
我在Java中有一个通用方法:
public static <T extends C> ArrayList<<MyClass<T>> methodOne(parameter1)
当前,我使用这种方法来获取特定类型的MyClass的ArrayList,如下所示(A和B是C的子类):
ArrayList<MyClass<A>> result = methodOne<A>(param1);
要么
ArrayList<MyClass<B>> result = methodOne<B>(param1);
现在,我还有另一个需求,它需要一个同时包含两种类型的MyClass的ArrayList:
ArrayList<MyClass> result = methodOne<MyClass>(param1);
但是,我无法从methodOne返回ArrayList<MyClass>
,因为它声明它返回了ArrayList<MyClass<T>>
对象。
我可以通过将methodOne更改为非泛型来解决此问题:
pubic static ArrayList<MyClass> methodOne(parameter1)
但是,当我可以在可能的情况下指定MyClass的类型时,我会感到更加安全。 如果我使用上面的声明,那么我将无法执行以下操作:
ArrayList<MyClass<A>> result = methodOne<A>(param1);
有什么方法可以保留当前的泛型方法并在需要时为MyClass指定类型,而在其他情况下(例如:当方法调用用两种MyClass类型填充ArrayList时)都可以省去该类型?
但是,将同时容纳两种类型的MyClass的ArrayList将容纳
MyClass<A>
对象和MyClass<B>
对象(而不是MyClass<superclass>
对象)
同时包含MyClass<A>
和MyClass<B>
应具有以下类型:
List<MyClass<? extends C>>
然后,您可以将MyClass<A>
和MyClass<B>
元素添加到列表中。
如果您需要您的方法在不同的时间返回不同的类型,则它必须以某种方式取决于该方法的参数。 因此,例如,如果methodOne()
将MyClass
实例作为参数,则可以定义这样的方法(请注意<T>
声明,使之成为通用方法 ):
public <T> List<MyClass<T>> methodOne(MyClass<T> param, ...)
然后,您可以让methodOne()
返回与传递的对象具有相同类型的列表:
List<MyClass<A>> result1 = methodOne(instanceOfA, ...);
List<MyClass<C>> result = methodOne((MyClass<C>)instanceOfA, ...);
如果您不打算传入所需类型的实例,则仍然可以通过传入该类型的Class
来摆脱它,如下所示:
public <T> List<MyClass<T>> methodOne(Class<T> clazz, ...)
并致电:
List<MyClass<A>> result1 = methodOne(A.class, ...);
List<MyClass<C>> result = methodOne(C.class, ...);
您更喜欢哪种选择取决于您的用例。
您必须使用此方法签名:
<T extends C> ArrayList<MyClass<? extends T>> methodOne(int param1)
这将返回C
及其子类的MyClass
对象列表。
像这样使用它:
ArrayList<MyClass<? extends C>> resultC = methodOne(123);
resultC.add(new MyClass<A>());
resultC.add(new MyClass<B>());
完整的示例代码:
import java.util.ArrayList;
interface C {}
class A implements C {}
class B implements C {}
class MyClass<X> {}
public class Generic {
public static void main(String[] args) {
ArrayList<MyClass<? extends A>> resultA = methodOne(123);
resultA.add(new MyClass<A>());
ArrayList<MyClass<? extends B>> resultB = methodOne(123);
resultB.add(new MyClass<B>());
ArrayList<MyClass<? extends C>> resultC = methodOne(123);
resultC.add(new MyClass<A>());
resultC.add(new MyClass<B>());
}
static <T extends C> ArrayList<MyClass<? extends T>> methodOne(int param1) {
return null;
}
}
您不能这样做,因为即使class A
扩展了class B
, List<A>
也不扩展List<B>
。 这是因为A
对象支持具有相同签名的B
所有属性和方法。
但是List<B>
有一个接受B
对象的add
方法,其中List<A>
仅接受A
元素。
但是addAll
方法具有不错的签名(对于List<E>
):
boolean addAll(Collection<? extends E> c)
因此,如果可以接受,您可以执行以下操作:
ArrayList<MyClass<? extends abstractAncestor>> l = new ArrayList<MyClass<? extends abstractAncestor>>();
l.addAll(method1<MyClass<A>>(param1));
l.addAll(method1<MyClass<B>>(param1));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.