generika a '? extends Xxx'

Kamil Podlesak kamil.podlesak na gmail.com
Čtvrtek Listopad 25 09:53:39 CET 2010


Krátká verze = praktická rada: Konstrukci ? extends (a super) se
snažte vždy vyhnout. Zvlášť u proměnných.

Pro správné pochopení je potřeba plně rozumět kovarianci a
kontravanrianci
(http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29),
nicméně i tak to nemusí být intuitivně vidět. Pokusím se to popsat
zjednodušeně "prakticky":

Pozn: předpokládejme   class C extends A

Proměnná typu DaoA<? extends A> totiž _neznamená_ "instance DaoA u
které si můži za T dostadit jakéhokoliv potomka A co právě mám". To by
bylo DaoA<A>

Proměnná typu DaoA<? extends A> ve skutečnosti znamená, že do ní můžu
přiřadit nějakou instanci DaoA, která má nějaký konkrétní parametr -
může se jednat o DaoA<A>, DaoA<B> nebo DaoA<C>, kompilátor to neví (?
extends A mu explicitně řeklo, že to nesmí vědět).
Když pak vidí dao.doSometning(new B()) tak se podívá na ten parametr a
vidí, že tím parametrem je nějaký typ který nezná. Může to být A, může
to být B, může to být ale klidně C! Pokud by tam dovolil předat new
B(), tak v tom posledním případě klidně může dojít ke
ClassCastException.

Kamil Podlešák

2010/11/25 Martin Beranek <martin.beranek na i.cz>:
> Tak si trošku odpovím sám. Je třeba použít T<? super B>, ale neřeší to
> můj problém...
>
> private class A {}
>
> private class B extends A {}
>
> private abstract class DaoA<T extends A> {
>    void doSomething(T param) {}
> }
>
> private class DaoB extends DaoA<B> {}
>
> a pak potrebuji
>
> DaoA<? extends A> dao = new DaoB();
> dao.doSomething(new B()); // nejde přeložit
>
>
>
> Dne 25.11.2010 08:06, Martin Beranek napsal(a):
>> Zdravím,
>>
>> proč toto nefunguje?
>>
>> private class B {}
>>
>> private class Test<T> {
>>     void doSomething(T param) {}
>> }
>>
>> a nekde potrebuji
>>
>> Test<? extends B> t = new Test<B>();
>> t.doSomething(new B()); // toto nelze zkompilovat
>>
>> diky
>>
>
> --
> Martin Beránek
> ICZ a.s., Pobočka Brno
> Londýnské náměstí 2/856, 639 00  Brno
> Tel.: +420 222 272 323
> Tel.: +420 222 272 111
> Fax.: +420 222 272 122
> mailto:martin.beranek na i.cz
> http://www.i.cz
>
>


Další informace o konferenci Konference