Here's what happens: you call start()with actual parameters that have a wildcard type ? extends Product, so the compiler infers that type by replacing a capture variable, such as CAP#2for ?, for Tin the call to run. So the type goes out of type List< Session< CAP#2 > >, where all we know is that 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]
:
( ∀S : S is-a T ) Session< S > is-a Session< ? extends T > [2]
, CAP#2 is-a Product, [2] :
Session< CAP#2 > is-a Session< ? extends Product > [3]
List< Session< CAP#2 > > is-NOT-a List< Session< ? extends Product > >
[1] [3] :
List< Session< CAP#2 > > is-a List< ? extends Session< ? extends Product > >
:
< T > List< Session< T > > start(
Criteria< ? extends T > criteria,
List< ? extends Property< ? extends T > > orders
)