No promiňte, ale jak koukám na tu diskuzi tak si nikdo i včetně autora článku nikdo nevšiml (tragikomedie je že to neví i lidi z coinu:-( ) že v části 5. Je operátor <> skutečně nezbytný a/nebo dostatečně obecný?
má chybu a to takovou že lze zapsat... viz jednoduchý test:
//kompilováno pod jdk6, javac kompilátor pouze upozorní na potenciální //unsafe operaci
public class CollectionTest {
@Test
public void testType() {
List<String> list = new ArrayList();
List<List<String>> list2 = new ArrayList();
List<List<List<String>>> list3 = new ArrayList();
Map<String, Collection<Integer>> map = new LinkedHashMap();
//list.add(new Integer(1));//nejde zkompilovat
list.add(String.valueOf("hello"));//toto jo
//list2.add(new Integer(2));//nejde zkompilovat
list2.add(new ArrayList());//tohle jo ! všimně te si že se nekontroluje typ !!!
List beztypovyList = list;
beztypovyList.add(new Integer(3)); //tohle projde i s tím pitomým diamantem!!!
//tohle projde
for (Object object : beztypovyList) {
System.out.println(object);
}
//tohle NEprojde ale spadne ! a spadne to i s tím pitomým diamantem!!!
for (String object : list) { //java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
System.out.println(object);
}
}
}
Ano, to prece plyne z toho, ze seznamy atd. jsou v bajtkodu vzdy tvoreny jako kolekce obecny objektu (Object), je to dokonce o par odstavcu vys vypsano (je tam volani konstruktoru z bajtkodu + metody add a get).
To znamena, ze prekladac muze v nekterych pripadech zkontrolovat tyto manipulace (vypise warning), ale pretypovani se objevi az v runtime.
Hmm mozna jsme se nepochopili: operator diamantu pouze slouzi k tomu, aby se na prave strane prirazeni pri konstrukci objektu (a nikde jinde) nemusel udavat genericky typ, nic jineho. Tudiz pokud uz puvodni varianta: List<String> list = new ArrayList<String>() povolovala typove nespravne operace (jako ze povoluje), diamant to nikak nevylepsi.
Ano to jsem psal Filipe, ale to mi pořád přijde zbytečné přidávat konstrukci navíc (lze udělat pouze u vytvoření nového objektu) místo aby u vytvoření nového objektu zrušili to upozornění! ;-)
Pokud si vygeneruješ class soubor tak v obou případech bude stejný takže se se to opravdu redukuje na výběr mezi zrušení upozornění nebo přidávat novou konstrukci
tak jediný důvod který jsem našel je že pokud
List<String> strings = new ArrayList();
strings.add("hello");
//přidělím při vytvoření nové kolekce
List<Integer> integers = new ArrayList(strings);
//tak dál už to je potenciálně nebezpečné ale pokud udělám
List<Integer> integers = new ArrayList<>(strings);
//tak mi to kompilátor nedovolí