通用通配符类型不应在返回参数中使用

是否可以说通用通配符类型不应该用在方法的返回参数中?

换句话说,声明一个如下所示的接口是有意义的:

interface Foo { Collection next(); } 

另外,可以说通用通配符类型仅在方法的参数声明中有意义吗?

在方法forms参数中使用通配符类型的主要好处是为用户提供传递的灵活性,比如说任何类型的CollectionList或实现Collection的任何东西(假设集合声明为Collection ) 。 您经常会发现自己在forms参数中使用通配符类型。

但理想情况下,您应该避免将它们用作方法的返回类型。 因为这样,您将强制该方法的用户在调用者端使用通配符类型,即使他们不想这样做。 通过使用通配符类型,你说,嘿! 这个方法可以返回任何类型的Collection ,所以你的工作就是照顾它。 你不应该这样做。 最好使用有界类型参数。 使用有界类型参数,将根据您传递的类型或方法调用的目标类型推断类型。

以下是Effective Java Item 28的引用

不要将通配符类型用作返回类型。 它不会为用户提供额外的灵活性,而是迫使他们在客户端代码中使用通配符类型。
正确使用的通配符类型对于类的用户几乎是不可见的。 它们使方法接受它们应该接受的参数并拒绝它们应该拒绝的参数。 如果类的用户必须考虑通配符类型,那么类的API可能有问题。

不,说这个是不可行的。

或者这样说:拥有这样的界面确实有意义。

想象一下以下内容

 interface Foo { Collection next(); } class FooInteger implements Foo { private final List integers = new ArrayList(); void useInternally() { integers.add(123); Integer i = integers.get(0); } @Override public Collection next() { return integers; } } // Using it: Foo foo = new FooInteger(); Collection next = foo.next(); Number n = next.iterator().next(); 

如果将返回类型写为Collection ,则无法返回包含T的子类型的集合。

是否需要具有这种返回类型取决于应用案例。 在某些情况下,可能只是必要的 。 但如果容易避免,那么你可以做到这一点。


编辑:编辑代码以指出差异,即您可能无法始终在内部选择类型。 但是,在大多数情况下,可以避免返回涉及通配符的内容 – 正如我所说的,如果可能的话,应该避免使用。

上面描述的示例仍应被视为强调关键点的示例 。 当然,虽然这样的实现是一种不好的做法,因为它暴露了内部状态。

在这个和类似的情况下,人们通常可以返回类似的东西

 return Collections.unmodifiableList(integers); 

并且,通过这种方式,将返回类型声明为ColletionunmodifiableList方法解决了暴露内部状态的问题,并且具有允许将类型参数更改为超类型的整洁属性,因为列表是……好吧,无论如何都是不可修改的。

为了避免警报(例如:Sonar),将Class替换为Class Class或根本不使用它。 只需归还一class