Generika Java

Ja

Generika Java
« kdy: 02. 08. 2014, 21:09:32 »
Ahoj, mám pár otázek k tomuto příkazu:

pif = (PlugInFilter) Class.forName(a).newInstance();

Metoda forName() vrací Class<?>, nemůže vracet Class<T>, protože není instanční, stejně tak je blbost, aby vracela např. Class<String>, tedy mě napadá, kdyby vracela surový typ, tedy Class, nebyl by vlastně rozdíl mezi Class<?> a Class, ne ?

Dále, metoda newInstance() vrací T, proč mi tedy IDE říká, že metoda vrací Object, neměla by vracet PlugInFilter ?

Snad mě chápete  ;D


Re:Generika Java
« Odpověď #1 kdy: 02. 08. 2014, 21:37:25 »
S tím, že je to statická metoda, to nijak nesouvisí. Nemělo by smysl, aby Class.forName() vracelo konkrétní typ, třeba Class<String>, protože místo toho už můžete rovnou v kódu použít String.class. A i kdybyste jako typový parametr použil nějakého předka, při tom volání není jak to ověřit, stejně by ve volání té funkce muselo být skryté explicitní přetypování - je lepší, když to udělá rovnou programátor, aspoň tím dá najevo, že ví, co dělá.
Surové typy jsou jen pro zpětnou kompatibilitu, v novém kódu by se vůbec neměly používat. Class<?> a Class je každé něco jiného, to druhé je surový typ a u něj neprobíhá žádná kontrola typových parametrů, v prvním případě se dál typové parametry kontrolují.
Ve vašem případě nemůže newInstance() vracet PlugInFilter, protože ji voláte na typu Class<?> nebo-li Class<? extends Object>, který jste získal voláním Class.forName(). Kdybyste tu metodu volal na typu Class<? extends PlugInFilter>, bude vám vracet PlugInFilter.

Ja

Re:Generika Java
« Odpověď #2 kdy: 03. 08. 2014, 13:04:46 »
Děkuji za odpověď, vím, jaký je rozdíl mezi surovým typem a žolíkem, už chápu, proč mi IDE tvrdí, že metoda newInstance() vrací Object.

Mám ještě poslední otázku, kdyby se programátoři Javy rozhodli, že metoda forName() nebude vracet Class<?> ale surový typ Class, tak by to v tomto konkrétním případě bylo jedno, výsledek by byl stejný, opakuji, že jsem si vědom rozdílu mezi žolíkem a surovým typem, je moje úvaha správná ?

Re:Generika Java
« Odpověď #3 kdy: 03. 08. 2014, 14:45:39 »
V tomto konkrétním případě by byl výsledek stejný, jenom by kompilátor vypsal varování, že se používá surový typ (tj. zastaralý kód).

Ja

Re:Generika Java
« Odpověď #4 kdy: 03. 08. 2014, 15:01:52 »
OK, díky.


Natix

Re:Generika Java
« Odpověď #5 kdy: 03. 08. 2014, 23:44:43 »
U java.lang.Class konkrétně rozdíl mezi raw a wildcard typem asi žádný není, ale třeba u kolekcí už to poznat jde.

List je list čehokoliv, tzn. že do něj můžu vložit objekt jakéhokoliv typu, a následně při čtení prvků můžu dostat cokoliv, takže typ vyčtených prvků je Object. Je to víceméně podobné jako List<Object>, ale myslím, že určitý rozdíl tam je (raw typy zahazují veškerou typovou kontrolu u všech metod, ve kterých daný raw objekt použiju).

List<?> je proti tomu list prvků neznámého (ale daného) typu. Při čtení prvků podobně jako u raw typu dostávám Objecty, ale při vkládání už je zásadní rozdíl: protože typ prvků listu neznám, tak vlastně do něj bezpečně nemůžu umístit nic. Resp. můžu tam umístit jednu jedinou hodnotu, která splňuje jakýkoliv typ, a to null. Nic jiného ale nemůžu.

Re:Generika Java
« Odpověď #6 kdy: 04. 08. 2014, 00:03:56 »
Pak jeste existujou typovy argumenty u metod; pak signatura metody vypada napriklad takto:
public static <K, V> Function<K, V> mapToFunction(Map<K, V> map)

Timto se da zajistit vazba mezi typy (je ti jedno, jakej to typ je, ale urcity veci musej bejt stejnyho typu, zde typ vraceny funkce bude zaviset na dodane mape.