JavaRush /Blog Java /Random-PL /Inicjalizacja podwójnego nawiasu klamrowego
Joysi
Poziom 41

Inicjalizacja podwójnego nawiasu klamrowego

Opublikowano w grupie Random-PL

1. Inicjalizacja podwójnego nawiasu klamrowego

Inicjalizacja przy użyciu podwójnych nawiasów klamrowych ( zwana dalej inicjalizacją podwójnych nawiasów ) to narzędzie Java służące do tworzenia kolekcji takich jak lista, zestaw i mapa jednocześnie z ich deklaracją.
Inicjalizacja podwójnego nawiasu - 1
Gdy potrzebujesz list ze stałymi elementami, takimi jak lista obsługiwanych produktów czy walut, zadeklarowanie listy jednocześnie z jej inicjalizacją poprawia czytelność kodu. Właśnie dlatego inicjalizacja z podwójnymi nawiasami zyskuje na popularności, ponieważ nie ma innych standardowych metod tworzenia kolekcji z jednoczesną inicjalizacją w kodzie. Niestety, w przeciwieństwie do innych języków programowania, Java nie obsługuje kolekcji literałów. Ze względu na to ograniczenie utworzenie niemodyfikowalnej listy nawet z niewielką liczbą elementów zmusza nas do napisania wielu linijek kodu w formie powtarzających się wywołań add()w celu dodania żądanych elementów z ostatecznym opakowaniem:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Jest to niepotrzebnie zbędny opis, który można uprościć. Listy statyczne wypełniajmy w dogodny dla nas sposób, czyli bezpośrednio w blokach statycznych podczas inicjalizacji, w czym Double bracepomoże nam inicjalizacja, pozwalająca nam napisać wszystko w jednej linijce:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
Podobnie Double braceinicjalizacja pomoże nam wypełnić wartości i HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
Wszystko wygląda elegancko, ale ma swoje wady, które sprawiają, że inicjalizacja z podwójnym nawiasem jest anty-wzorem. Przyjrzymy się im bliżej w następnym rozdziale.

Plusy i minusy inicjalizacji podwójnego nawiasu klamrowego.

DoubleInicjalizacja nawiasów klamrowych wykorzystuje utworzenie anonimowej klasy wewnętrznej . Jednak to, co początkowo jest ukryte na powierzchni, Double braceinicjalizacja tworzy klasę z dalszą inicjalizacją jej instancji za każdym razem, gdy jej używasz. Dodatkowo stosowane jest ukryte odniesienie do tej prywatnej klasy, co może nas naprowadzić na możliwe wycieki pamięci. Nie możesz także używać operatora widma dla typów generycznych (operator rombu < >), ponieważ nie możemy uzyskać dostępu do wnętrza anonimowej klasy.
(Od tłumacza: Jeszcze bardziej szczegółowo:
po pierwszej {tworzona jest wewnętrzna anonimowa klasa, po drugiej {następuje inicjalizacja podczas tworzenia instancji klasy, w której mamy dostęp do pól i metod zewnętrznej ( w stosunku do klasy anonimowej).
Plusy:
  1. Redukcja linii w kodzie
  2. Tworzenie i inicjalizacja w jednym wyrażeniu.
Wady:
  1. Tworzenie anonimowej klasy ukrytej przed tobą.
  2. Co kosztuje nas dodatkowe koszty za jego instancję za każdym razem, gdy z niego korzystamy.
  3. Za każdym razem tworzone jest ukryte odniesienie do niego, co może prowadzić do wycieków pamięci.
Werdykt: Ze względu na powyższe wady i istnienie alternatyw dla podwójnych nawiasów klamrowych, inicjalizacja jest postrzegana jako antywzorzec w świecie Java. Uratuj kotka

Alternatywy dla inicjalizacji podwójnych nawiasów klamrowych w Javie

Dobra wiadomość jest taka, że ​​istnieją inne sposoby osiągnięcia tych samych celów w Javie. Możemy zaimplementować w jednym wierszu kodu utworzenie i inicjalizację ArrayList za pomocą konstruktora Copy z klasy Collection, jak pokazano poniżej:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()zwróci nam listę o stałej długości przekazanej ArrayListkonstruktorowi kopiującemu. Pamiętaj o różnicy pomiędzy listami o stałej długości zwracanymi przez Arrays.asList()i Collections.unmodifiableList(): nie możesz dodawać ani usuwać elementów ArrayList- , ale możesz zmieniać element według indeksu za pomocą set(), czego nie można zrobić w przypadku listy zwróconej przez Collections.unmodifiableList(). Jeśli chcesz uzyskać małą listę, jest to najlepszy sposób, chociaż będzie mniej przejrzysty dla Setinnych kolekcji, więc będziesz musiał ją utworzyć Listprzed utworzeniem Setopcji -a. Jest to jednak nadal lepsze niż inicjalizacja z podwójnym nawiasem klamrowym, ponieważ w tym przypadku dodatkowa wewnętrzna anonimowa klasa nie jest tworzona za każdym razem, gdy jest używana. Jeśli używasz Java 8, masz inną alternatywną metodę. Interfejs API strumienia JDK 8 pomoże Ci stworzyć małe kolekcje, łącząc Stream Factorymetody wyjściowe w kolekcję List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
Zamiast tego Setmożesz użyć Collectors.toSet()metody Collectors.toList()jak poniżej:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
Nawiasem mówiąc, Stream collectmetody nie gwarantują, że generowane przez nie zbiory będą chronione przed zmianami. W Javie 8 zwracane przez nie kolekcje (takie jak - ArrayList, HashSeti HashMap) są dość powszechne (możemy je zmienić), ale fakt ten może zostać poprawiony w przyszłych wydaniach JDK. To wszystko na razie o Double braceinicjalizacji w Javie. Ten szablon jest akceptowalny w przypadku testów i wersji demonstracyjnych, ale nie jest wystarczająco dobry do użytku produkcyjnego. Ze względu na swoje nieodłączne wady, inicjalizacja z podwójnym nawiasem stała się obecnie antywzorcem, szczególnie biorąc pod uwagę dostępne alternatywy. Ja sam nadal wykorzystuję tę konstrukcję do inicjalizacji map statycznych i tyle. Wolę bowiem Listtworzyć Collectionspoprzez połączenie z tworzeniem Array.asListw jego konstruktorze. A jeśli użyję Java 8 - projekt wykorzystujący Stream API i collect(). Powiązane artykuły: Jeśli podobał Ci się ten samouczek i chcesz dowiedzieć się więcej o wzorcach, zasadach i najlepszych praktykach programowania w języku Java, możesz także zapoznać się z innymi artykułami w naszej witrynie . Zalecana lektura: Jeśli chcesz dowiedzieć się więcej o wzorcach i najlepszych praktykach, przeczytaj Efektywne programowanie Joshuy Blocha , żadna książka nie zastąpi jej. A jeśli znasz już biegle Javę i szukasz książki o wzorcach projektowych, której humorystyczny sposób prezentacji jest ciekawy i łatwy w odbiorze, zwróć uwagę na „Head First. Wzorce projektowe" .
Od tłumacza: Celowo podałem link do oryginalnej książki Blocha, gdyż jej tłumaczenie na rosyjski nie powiodło się (np. Builder = konstruktor).
Tłumaczenie artykułu Co to jest inicjalizacja podwójnego nawiasu w Javie? Przykład przeciwdziałania wzorowi (opublikowany w październiku 2015 r.).
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION