Java泛型与T和?的区别?延伸T.

Hir*_*ida 4 java generics extends wildcard

有用.

方法声明

<T> Session<T> start(Criteria<T> criteria, List<Property<T>> orders);
Run Code Online (Sandbox Code Playgroud)

用法

Criteria<? extends Product> criteria = Utils.getCriteria();
Session<? extends Product> session = null;
session = Service.start(criteria, null);
Run Code Online (Sandbox Code Playgroud)

它不起作用.

方法声明

<T> List<Session<T>> start(Criteria<T> criteria, List<Property<T>> orders)
Run Code Online (Sandbox Code Playgroud)

用法

Criteria<? extends Product> criteria = Utils.getCriteria();
List<Session<? extends Product>> sessions = null;
sessions = Service.start(criteria, null);
Run Code Online (Sandbox Code Playgroud)

错误信息

Type mismatch: cannot convert from List<Session<capture#2-of ? extends Product>> to List<Session<? extends Product>>
Run Code Online (Sandbox Code Playgroud)

如果我将方法声明更改为此,它可以工作.

<T> List<Session<? extends T>> start(Criteria<? extends T> criteria, List<Property<? extends T>> orders)
Run Code Online (Sandbox Code Playgroud)

为什么这个方法声明不起作用?

<T> List<Session<T>> start(Criteria<T> criteria, List<Property<T>> orders)
Run Code Online (Sandbox Code Playgroud)

Jud*_*tal 5

这是正在发生的事情:你start()使用通配符类型的实际参数进行调用? extends Product,因此编译器推断出该类型,在一个捕获变量中替换CAP#2为for ?,用于T启动调用.因此,出现的类型List< Session< CAP#2 > >是我们所知道的类型CAP#2 is-a Product.

您正尝试将该结果分配给类型的变量List< Session< ? extends Product > >,该变量表示会话的异构列表.我敢打赌,如果你把它分配给List< ? extends Session< ? extends Product > >它可以工作的类型的变量.

规则如下:

( ?S : S is-a T ) G< S > is-a G< ? extends T >                       [1]
Run Code Online (Sandbox Code Playgroud)

所以:

( ?S : S is-a T ) Session< S > is-a Session< ? extends T >           [2]
Run Code Online (Sandbox Code Playgroud)

特别是,CAP#2 is-a Product从[2]我们得到:

Session< CAP#2 > is-a Session< ? extends Product >                   [3]
Run Code Online (Sandbox Code Playgroud)

但:

List< Session< CAP#2 > > is-NOT-a List< Session< ? extends Product > >
Run Code Online (Sandbox Code Playgroud)

但是,从[1]和[3]我们得到:

List< Session< CAP#2 > > is-a List< ? extends Session< ? extends Product > >
Run Code Online (Sandbox Code Playgroud)

无论如何,我建议以下声明对您的客户最慷慨:

< T > List< Session< T > > start(
    Criteria< ? extends T > criteria,
    List< ? extends Property< ? extends T > > orders
)
Run Code Online (Sandbox Code Playgroud)