Petr Balat napsal(a):
> - V Javě je Iterable<String> potomkem Iterable<Object> protože je to v
> reálu
> ten samej objekt - pouze překladač nás může chránit tak jako máte ve 2
> příkladě.. (to samé pro List)

Není. Za běhu jsou Iterable<String> a Iterable<Object> reprezentovány
třídou Iterable, nicméně pro překladač jsou to dva různé typy a
Iterable<String> není potomkem Iterable<Object>.
Najdete to např. i na té stránce, jejíž odkaz uvádíte v jednom z
předchozích mailů:

http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29

"Generics were introduced in Java in Java 5.0 to allow type-safe generic
programming. Unlike arrays, generic classes are neither covariant nor
contravariant. For example, neither List<String> nor List<Object> is a
subtype of the other:"

> - V druhém případě souhlasím že koo. by byla nežádoucí v List to ale nikdo
> nepožaduje.
>
> jinak předpokládám že jste měl na mysli koo. a kontra. v parametrech jako
> např.
> http://etymon.blogspot.com/2007/02/java-generics-and-covariance-and.html
>
> já ale měl spíše namysli koo. v generikách v Iterable jako např. v
> http://msdn.microsoft.com/library/dd799517.aspx

Tohle je zajímavá vlastnost, nová v .NET 4. Pro javisty ji krátce popíšu:

Pokud interface používá typový parametr pouze jako návratový typ metod,
lze typový parametr označit jako kovariantní (pomocí klíčového slova out):

interface IEnumerable<out T> { ... }

A pokud interface používá typový parametr pouze pro typy parametrů metod,
lze typový parametr označit jako kontravariatní (pomocí klíčového slova
in):

interface IComparer<in T> { ... }

Pak je možné toto:

IEnumerable<Derived> d = ...;
IEnumerable<Base> b = d;  // plyne z kovariantního navrátového typu

A toto:

IComparer<Base> b = ...;
IComparer<Derived> d = b;

Z.T.
-- 
Zdenek Tronicek
FIT CTU in Prague

>
> Dne 20. září 2011 8:02 "Zdeněk Troníček" <[email protected]> napsal(a):
>
>> Dobrý den,
>>
>> kovariance a kontravariance s tímto nesouvisí (navíc Java kovariantní
>> return má). Váš příklad
>>
>> Iterable<Object> o = new ArrayList<String>();
>>
>> nejde přeložit jednoduše z toho důvodu, že v Javě není Iterable<String>
>> potomkem Iterable<Object>.
>>
>> A to z jednoduchého důvodu. Kdyby např. List<String> byl potomkem
>> List<Object>, pak by šlo napsat:
>>
>> List<String> s = new ArrayList<String>();
>> List<Object> o = s;
>> o.add(new Object()); // v seznamu řetězců máme Object!!!
>>
>> Z.T.
>> --
>> Zdenek Tronicek
>> FIT CTU in Prague
>>
>>
>> Petr Balat napsal(a):
>> > dobrý den,
>> >
>> > bohužel java překladač neumí Kovarianci a kontravarianci
>> >
>> http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
>> > (viz google -> Covariance a Contravariance) proto bude java varovat
>> při
>> > výrazech typu
>> > Cache<String, String> cache =
>> ComponentFactory.getComponent(Cache.class)
>> > nebo např. nepůjde zkompilovat Iterable<Object> o = new
>> > ArrayList<String>();
>> > ale bohužel se i při překladu informace o typu v parametru ztratí
>> takže
>> > vás
>> > ani runtime neochrání pro vložení jiných typů než jsou definované.
>> >
>> > Předpokládám ale že Vám jde o typovou kontrolu při kompilaci kde někde
>> > pouzijete Class<Cache<String,String>> cls=...;
>> > Cache<String, String> = cls.createInstance();
>> > můžete vytvorit tridu ktera bude dedit po Cache<String, String> potom
>> Vam
>> > to
>> > kompilator vezme.
>> >
>> > Ale myslím si že si tím nic nezachráníte (kdekoliv muze nekdo
>> > Cache<string,
>> > string> pretypovat na Cache a vlozit jiny typ a spadne to az pri
>> > vyzvednuti
>> > objektu a jeho typ) ale uměle budou vytvořeny zbytečné nové třídy
>> takže
>> > bych
>> > se s varováním smířil nebo použil pokročilejší programovací jazyk jako
>> > např.
>> > c# :-)
>> >
>> > S pozdravem
>> > Petr Balat
>> >
>> > 2011/9/19 Petr Novak <[email protected]>
>> >
>> >> Zdravím konferenci,
>> >>
>> >>  narazil jsem na problém s generic a nevím, jestli je problém jen v
>> mé
>> >> hlavě, nebo v javě a google mi zatím moc nepomohl, protože ani nevím
>> jak
>> >> se
>> >> řádně zeptat.
>> >>
>> >> Problém je s následujícím kouskem kódu:
>> >>
>> >> Class<Cache<String,String>> cls = Cache.class;      // nelze
>> >> zkompilovat,
>> >> eclipse mi nabízí, abych  Class<Cache<String,String>> převedl jen na
>> >>  Class<Cache>, ale to pak má warning, že používám RAW typy, což ani
>> >> nechci
>> >> :).
>> >>
>> >> Myslel jsem, že půjde zapsat
>> >> Class<Cache<String,String>> cls = Cache<String,String>.class; //ale
>> toto
>> >> nelze kompilovat už vůbec, řve to, že Cache není definována a že ty
>> >> závorky
>> >> tam nemají být a kdo ví co ještě.
>> >>
>> >> Definice rozhraní cache je jednoduchá:  public interface Cache<K,
>> >> V>{....}
>> >>
>> >> Původní problém je trochu jiný, ale důsledek stejný, ve skutečnosti
>> >> potřebuji:
>> >> Cache<String, String> cache =
>> >> ComponentFactory.getComponent(**Cache.class,
>> >> CACHE_NAME);  //toto ale opět hází warning
>> >>
>> >> definice té metody je:
>> >> public static <T> T getComponent(final Class<T> compClass, final
>> String
>> >> compName);
>> >>
>> >> čekal jsem možnost použití
>> >> Cache<String, String> cache = UESComponentFactory.**
>> >> getComponent(Cache<String,**String>.class, TEST_CACHE);  //ale jak
>> plyne
>> >> z
>> >> výše uvedeného, toto nelze kompilovat
>> >>
>> >>
>> >>
>> >> Jediné řešení, které funguje compilačně a bez warningu je:
>> >>    @SuppressWarnings("unchecked")
>> >>    Cache<String, String> cache =
>> >> UESComponentFactory.**getComponent(Cache.class,
>> >> TEST_CACHE);
>> >>
>> >> ale to se mi nelíbí.
>> >>
>> >>
>> >> Nemáte někdo nějaký nápad, jak v javě zapsat  správně
>> >>  Cache<String,String>.class  ?  Klidně to můžete zkusit pro
>> >>  Map<String,String>  dopadne to stejně.
>> >>
>> >> Díky za veškeré podněty
>> >>
>> >> Petr
>> >>
>> >>
>> >>
>> >
>>
>>
>

Odpovedet emailem