generika a '? extends Xxx'

"Zdeněk Troníček" tronicek na fit.cvut.cz
Čtvrtek Listopad 25 15:34:03 CET 2010


Konstrukci ? extends Neco bych nezavrhoval, protoze je užitečná pro
parametry metody.
Př.: metoda, která provede nějakou operaci se všemi prvky seznamu, v němž
je každý prvek typu Number.

void perform(List<? extends Number> p) {
    for (Number n : p) {
        process(n);
    }
}

void process(Number n) { ... }

Takto lze metodu perform volat s parametrem typu List<Integer> i
List<Double>.

Z.
-- 
Zdenek Tronicek
FIT CTU in Prague


Kamil Podlesak napsal(a):
> 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