Mar*_*tin 12 java generics interface wildcard
如果你想存储一个类型的对象数组,MyInterface以下两者都是可以接受的,如果是这样的话你何时会使用第二个形式而不是第一个?
i)仅使用接口: -
List<MyInterface> mylist = new ArrayList<MyInterface>();
Run Code Online (Sandbox Code Playgroud)
ii)使用通用通配符: -
List<? extends MyInterface> mylist = new ArrayList<? extends MyInterface>();
Run Code Online (Sandbox Code Playgroud)
编辑:
至于到目前为止的答案已经指出,第二号将无法编译.我和案例iii有什么区别:
iii)仅在参考文献中使用通用通配符: -
List<? extends MyInterface> mylist = new ArrayList<MyInterface>();
Run Code Online (Sandbox Code Playgroud)
第二个不会编译.想像:
A implements MyInterface
B implements MyInterface
Run Code Online (Sandbox Code Playgroud)
然后以下将匹配您的第二个表达式,但不会编译:
// incorrect
List<A> mylist = new ArrayList<B>();
Run Code Online (Sandbox Code Playgroud)
更正:错误的一个:
List<? extends MyInterface> mylist = new ArrayList<MyInterface>();
Run Code Online (Sandbox Code Playgroud)
从某种意义上来说它确实是编译的,但你不能在其中添加MyInterface的任何子类.令我感到困惑但是正确 - 在我阅读了解释之后.同样的原因:通配符可以被视为例如:
// I know this is not compileable; this is internal compiler "thinking".
// Read it as "somewhere someone may instantiate an ArrayList<A> and pass
// it down to us; but we cannot accept it as something that could be
// potentially used as List<B>"
List<A> mylist = new ArrayList<MyInterface>();
Run Code Online (Sandbox Code Playgroud)
所以这不起作用:
mylist.add(b);
Run Code Online (Sandbox Code Playgroud)
反之亦然.编译器拒绝执行那些可能不正确的操作.
允许您将MyInterface的任何子类添加到mylist的选项是:
List<MyInterface> mylist = new ArrayList<MyInterface>();
Run Code Online (Sandbox Code Playgroud)
如果您要存储类型MyInterface的对象,则更好的方法(可编译)是-
Run Code Online (Sandbox Code Playgroud)List<MyInterface> mylist = new ArrayList<MyInterface>();
但是,如果要在method参数中使用,则可以使用选项2(有界通配符类型)来提高API的灵活性。
Run Code Online (Sandbox Code Playgroud)public void someMethod(List<? extends MyInterface> myInterfaces);
编辑:
上面的代码将提供更大的灵活性API,因为泛型类型是不变的,因此,如果您具有-
public class A implements MyInterface {
// some implementation
}
Run Code Online (Sandbox Code Playgroud)
并且如果someMethod具有参数类型List<MyInterface>,则将无法使用List<A>,这将迫使API用户在另一侧List使用类型创建MyInterface-
List<? extends MyInterface>允许传递List<A>给someMethod..客户端通常具有,List<ActualObject>因此提供参数更灵活将采用任何实现,MyInterface
同时不要将通配符类型用作返回类型,例如
Run Code Online (Sandbox Code Playgroud)public List<? extends MyInterface> someMethod();
如果类的用户必须考虑通配符类型,则类的API可能存在问题。
List<? extends MyInterface>表示 的某个子类型的列表MyInterface,但我们不知道是哪个子类型。
由于我们不知道实际使用的是哪种子类型,因此我们不能在其中放入任何对象(因为我们无法确保它是该子类型的元素)。
我们可以从这样的列表中取出对象,并知道它是一个实现 的对象MyInterface,但仅此而已。
| 归档时间: |
|
| 查看次数: |
7199 次 |
| 最近记录: |