【问题标题】:Java - Using "<? extends Interface>" vs Interface only [duplicate]Java - 使用“<?扩展接口>”与仅接口[重复]
【发布时间】:2017-02-28 15:23:46
【问题描述】:

我看过一些代码如下

public interface IBean {

}

以及它在某些地方的用法

public void persist(List<? extends IBean> beansList) {

}

但同样可以用下面的代码实现

public void persist(List<IBean> beansList) {

}

那么这两种方法有什么区别,都是必须继承IBean接口的例外对象?

这是 bean 类

public class Category implement IBean {
  //related fields
}

public class Product implement IBean {
  //related fields
}

【问题讨论】:

    标签: java generics interface


    【解决方案1】:

    您可以将List&lt;Category&gt; 传递给public void persist(List&lt;? extends IBean&gt; beansList),但不能将List&lt;Category&gt; 传递给public void persist(List&lt;IBean&gt; beansList)

    另一方面,您可以将List&lt;IBean&gt; 传递给这两种方法。

    【讨论】:

    • 你是对的,但为什么呢? Category 是一个 IBean,所以它应该接受它吗?或者当我们使用像 List> 这样的泛型时规则是不同的
    • @PHPAvenger List&lt;Category&gt; 不是List&lt;IBean&gt; 的子接口。 List&lt;Category&gt; 可能只包含Category 实例(或Category 的子类实例),而List&lt;IBean&gt; 也可能包含Product 实例。
    • 太棒了,现在说得通了
    【解决方案2】:

    原因是泛型是不变的。例如,这意味着您不能在需要 List&lt;Number&gt; 的地方使用 List&lt;Integer&gt;

    但是当转向通配符时,你可以绕过这个限制。因此,当您真正拥有 List&lt;Product&gt; 时,您将无法将其传递给需要 List&lt;IBean&gt; 的方法 - 您必须先以某种方式转换列表。准确地说:你会做一个“硬”的演员;因为“转换”通用列表没有意义,因为无论如何都会在运行时启动类型擦除!

    通过在方法定义中使用通配符,您可以允许传递使用扩展类型的“真实”子类的列表;不需要丑陋的演员表。

    【讨论】:

      猜你喜欢
      • 2015-10-16
      • 2023-03-22
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 2012-10-23
      • 2011-01-14
      相关资源
      最近更新 更多