是否可以说通用通配符类型不应该用在方法的返回参数中?
换句话说,声明一个如下所示的接口是有意义的:
interface Foo<T> {
Collection<? extends T> next();
}
Run Code Online (Sandbox Code Playgroud)
另外,可以说通用通配符类型仅在方法的参数声明中有意义吗?
Roh*_*ain 21
使用通配符类型的主要好处,比如方法形式参数,是为用户提供灵活性来传递,比如任何类型的Collection,List或者任何实现Collection的东西(假设集合被声明为Collection<?>).您经常会发现自己在形式参数中使用通配符类型.
但理想情况下,您应该避免将它们用作方法的返回类型.因为这样,您将强制该方法的用户在调用者端使用通配符类型,即使他们不想这样做.通过使用通配符类型,你说,嘿!这种方法可以返回任何类型的Collection,所以你的工作就是照顾它.你不应该这样做.最好使用有界类型参数.使用有界类型参数,将根据您传递的类型或方法调用的目标类型推断类型.
以下是Effective Java Item 28的引用:
不要将通配符类型用作返回类型.它不会为您的用户提供额外的灵活性,而是迫使他们在客户端代码中使用通配符类型.
正确使用的通配符类型对于类的用户几乎是不可见的.它们使方法接受它们应该接受的参数并拒绝它们应该拒绝的参数.如果类的用户必须考虑通配符类型,那么类的API可能有问题.
不,这样说是不可行的。
或者这样说:拥有这样的界面确实有意义。
想象以下
interface Foo<T>
{
Collection<? extends T> next();
}
class FooInteger implements Foo<Number>
{
private final List<Integer> integers = new ArrayList<Integer>();
void useInternally()
{
integers.add(123);
Integer i = integers.get(0);
}
@Override
public Collection<? extends Number> next()
{
return integers;
}
}
// Using it:
Foo<Number> foo = new FooInteger();
Collection<? extends Number> next = foo.next();
Number n = next.iterator().next();
Run Code Online (Sandbox Code Playgroud)
如果将返回类型编写为Collection<T>,则无法返回包含子类型 的集合T。
是否需要这样的返回类型取决于应用程序案例。在某些情况下,它可能只是必要的。但如果很容易避免,那么你可以这样做。
编辑:编辑代码以指出不同之处,即您可能并不总是能够在内部选择类型。然而,在大多数情况下,返回的东西,包括一个通配符可以被避免的-正如我说的,如果可能的话,应尽量避免。
上面勾画的例子仍应被视为强调关键点的例子。虽然,当然,这样的实现将是一种不好的做法,因为它暴露了一个内部状态。
在这种和类似的情况下,人们通常可以返回类似
return Collections.<Number>unmodifiableList(integers);
Run Code Online (Sandbox Code Playgroud)
通过这种方式,将返回类型声明为Colletion<Number>: 该unmodifiableList方法解决了公开内部状态的问题,并具有允许将类型参数更改为超类型的简洁属性,因为该列表是……好吧,无论如何都是不可修改的。
| 归档时间: |
|
| 查看次数: |
13587 次 |
| 最近记录: |