Si può leggerlo e ripeterlo più e più volte, come è già successo molte volte. In un commento alla tua domanda, Philipp ha già collegato a una domanda su Stackoverflow che tenta di rispondere . Per me, la spiegazione di Zio Bob ha fatto il trucco.
Scrive (accanto a molte altre cose buone):
A List<? super Shape> is a list into which you may add Shapes. Another way to think of this is that the type <? super T> is an unknown type that T can substitute for. You may have to read that several times before you understand it. I certainly did. So here's yet another way to think about it. The type <? super T> is a type that T is derived from. It is a base class of T. Clearly if D is derived from B then you can put D instances into a List<B>. Likewise, since T derives from <? super T>, you can put T instances into a List<? super T>. Follow? No? Neither did I for awhile. It takes a bit of getting used to.
Che cosa significa alla fine è che la tua ipotesi di poter mettere i super-tipi di Manager nella tua List<? super Manager> è sbagliata. Questo non è ciò che si intende qui. La parola chiave super risolve il problema di non essere in grado di inserire elementi in luoghi generici mentre sei riuscito a ottenere un po 'di out (con extends ).
Immagina due coppie, una che estenda Manager, una che "la superi":
Pair<? extends Manager> subPair = new Pair<Manager>();
Pair<? super Manager> superPair = new Pair<Manager>();
Ciò che puoi mai fare, è inserire un Employee in uno di questi:
subPair.setFirst(new Employee());
superPair.setFirst(new Employee());
Se vuoi manager, i dipendenti non saranno mai abbastanza. Ed è peggio: non puoi nemmeno inserire un Executive nel tuo subPair , anche se Executive extends Manager . Non compilerà neanche:
subPair.setFirst(new Executive());
Modifica
Perché? Bene, il tuo generico subPair fa sempre riferimento ad alcuni "espliciti" Pair , Pair<Manager> in questo caso. Potrebbe anche essere riferito a un Pair<CoManager> (con CoManager extends Manager ). Java non conoscerà il tipo esplicito effettivamente utilizzato e quindi non può consentire le inserzioni.
Ma super viene in soccorso. Con super puoi inserire Manager e i loro sottotipi in Pair . Ed è ciò che super è per: Inserimento.
superPair.setFirst(new Executive());
Modifica: Qual è il motivo per cui funziona? Mentre extends ti garantisce un tipo un po ' che implementa (o deriva da) Manager , super ti garantisce qualsiasi tale tipo. Quindi, mentre con extends ottieni un tipo specifico con (almeno) l'interfaccia Manager , con super puoi inserire qualsiasi tipo con Manager interfaccia.
E per l'immagine più grande, suggerisco davvero di leggere l'articolo di Uncle Bob.