Problem z
List<String> list = new LinkedList();
jest to, że po lewej stronie używasz typu ogólnego, aList<String>
po prawej stronie używasz typu surowegoLinkedList
. Surowe typy w Javie istnieją tylko dla kompatybilności z kodem pre-generics i nigdy nie powinny być używane w nowym kodzie, chyba że jest to absolutnie konieczne.
Teraz, jeśli Java miała generyczne od samego początku i nie miała typów, takich jak te LinkedList
, które zostały pierwotnie utworzone, zanim miała generyczne, prawdopodobnie mogłaby to zrobić, aby konstruktor typu ogólnego automatycznie ustawiał parametry typu od lewej -ręczna strona zadania, jeśli to możliwe. Ale tak się nie stało i musi traktować typy surowe i typy ogólne inaczej dla kompatybilności wstecznej. To sprawia, że muszą stworzyć nieco inny , ale równie wygodny sposób deklarowania nowej instancji obiektu ogólnego bez konieczności powtarzania parametrów typu ... operator diamentu.
Jeśli chodzi o oryginalny przykład List<String> list = new LinkedList()
, kompilator generuje ostrzeżenie dla tego zadania, ponieważ musi. Rozważ to:
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
Istnieją środki generyczne, które zapewniają ochronę podczas kompilacji przed robieniem złych rzeczy. W powyższym przykładzie użycie typu raw oznacza, że nie otrzymujesz tej ochrony i wystąpi błąd w czasie wykonywania. Dlatego nie powinieneś używać typów surowych.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
Operator diamentów pozwala jednak zdefiniować prawą stronę przypisania jako prawdziwą ogólną instancję z tymi samymi parametrami typu co lewa strona ... bez konieczności ponownego wpisywania tych parametrów. Pozwala zachować bezpieczeństwo leków generycznych przy prawie takim samym wysiłku jak przy użyciu typu raw.
Myślę, że kluczową rzeczą do zrozumienia jest to, że typy surowe (bez <>
) nie mogą być traktowane tak samo jak typy ogólne. Po zadeklarowaniu typu surowego nie uzyskuje się żadnych korzyści ani sprawdzania typu generyków. Trzeba też pamiętać, że generyczne są częścią języka Java ogólnego przeznaczenia ... nie dotyczą tylko konstruktorów bez argonu Collection
!