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 >> >> >> >> >> >> >> > >> >> >
