Java-使用“ <?扩展接口>”与仅接口

PHP*_*ger 5 java generics interface

我看过一些代码如下

public interface IBean {

}
Run Code Online (Sandbox Code Playgroud)

及其在某些地方的用法

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

}
Run Code Online (Sandbox Code Playgroud)

但是可以使用以下代码来实现

public void persist(List<IBean> beansList) {

}
Run Code Online (Sandbox Code Playgroud)

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

这是bean类

public class Category implement IBean {
  //related fields
}

public class Product implement IBean {
  //related fields
}
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 5

您可以传递List<Category>to public void persist(List<? extends IBean> beansList),但不能传递List<Category>to public void persist(List<IBean> beansList)

另一方面,您可以将 a 传递List<IBean>给这两种方法。


Gho*_*ica 5

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

但是当使用通配符时,您可以绕过该限制。因此,当您确实拥有 a 时,List<Product>您将无法将其传递到期望的方法中List<IBean>- 您必须首先以某种方式转换列表。准确地说:你会做一个“硬”演员;因为“转换”通用列表是没有意义的,因为类型擦除无论如何都会在运行时启动!

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