JavaRush /Java Blog /Random-KO /이중 중괄호 초기화
Joysi
레벨 41

이중 중괄호 초기화

Random-KO 그룹에 게시되었습니다

1. 이중 중괄호 초기화

이중 중괄호를 사용한 초기화( 이하 이중 중괄호 초기화 )는 선언과 동시에 목록, 집합 및 맵과 같은 컬렉션을 생성하기 위한 Java 도구입니다.
이중 중괄호 초기화 - 1
지원되는 제품 목록이나 통화 단위 등 고정 요소가 포함된 목록이 필요한 경우 초기화와 동시에 목록을 선언하면 코드 가독성이 향상됩니다. 코드에서 동시 초기화를 사용하여 컬렉션을 생성하는 다른 표준 방법이 없기 때문에 이중 중괄호 초기화가 인기를 얻고 있는 이유입니다. 불행하게도 다른 프로그래밍 언어와 달리 Java는 리터럴 컬렉션을 지원하지 않습니다. 이러한 제한으로 인해 적은 수의 요소 add() 수정 불가능한 목록을 생성하면 최종 래핑으로 원하는 요소를 추가하기 위해 반복 호출 형식으로 많은 코드 줄을 작성해야 합니다 .
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
이는 단순화할 수 있는 불필요하게 중복되는 설명입니다. 우리에게 편리한 방식으로, 즉 초기화 중에 정적 블록에 직접 정적 목록을 채워 보겠습니다. Double brace초기화가 도움이 되어 모든 것을 한 줄에 작성할 수 있습니다.
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
마찬가지로 Double brace초기화는 값과 다음을 입력하는 데 도움이 됩니다 HashMap.
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
모두 매우 우아해 보이지만 이중 중괄호 초기화를 안티 패턴으로 만드는 단점이 있습니다. 다음 장에서 이에 대해 더 자세히 살펴보겠습니다.

이중 중괄호 초기화의 장점과 단점

Double중괄호 초기화에서는 익명의 내부 클래스 생성을 사용합니다 . 그러나 초기에 표면에 숨겨진 것은 Double brace초기화를 통해 사용할 때마다 해당 인스턴스를 추가로 초기화하는 클래스를 생성하는 것입니다. 또한 이 비공개 클래스에 대한 숨겨진 참조가 사용되므로 메모리 누수가 발생할 수 있습니다. 또한 익명 클래스 내부에 접근할 수 없기 때문에 제네릭에 고스트 연산자(다이아몬드 연산자 < >)를 사용할 수 없습니다.
(번역자의 말: 다시 한 번 더 자세히 설명합니다.
첫 번째 이후에는 {내부 익명 클래스가 생성되고, 두 번째 이후에는 {클래스의 인스턴스를 생성할 때 초기화가 발생하며, 여기서 외부 클래스의 필드와 메서드에 액세스할 수 있습니다( 익명) 클래스에 상대적입니다.)
장점:
  1. 코드 줄 줄이기
  2. 하나의 표현식으로 생성 및 초기화.
단점:
  1. 당신에게 숨겨진 익명 클래스를 만듭니다.
  2. 인스턴스를 사용할 때마다 인스턴스에 대한 추가 비용이 발생합니다.
  3. 이에 대한 숨겨진 참조가 생성될 때마다 메모리 누수가 발생할 수 있습니다.
평결: 위의 단점과 이중 중괄호에 대한 대안의 존재로 인해 초기화는 Java 세계에서 안티 패턴으로 간주됩니다. 새끼 고양이를 구해주세요

Java의 이중 중괄호 초기화에 대한 대안

좋은 소식은 Java에서 동일한 목표를 달성할 수 있는 다른 방법이 있다는 것입니다. 아래와 같이 Collection 클래스의 Copy 생성자를 사용하여 ArrayList의 생성 및 초기화를 한 줄의 코드로 구현할 수 있습니다.
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()ArrayList복사 생성자 에 전달된 고정 길이 목록을 반환합니다 . Arrays.asList()에서 반환된 고정 길이 목록의 차이점을 기억하세요 Collections.unmodifiableList(). - 의 요소를 추가하거나 제거할 수는 없지만 ArrayList를 사용하여 인덱스로 요소를 변경할 수 있습니다 set(). 에서 반환된 목록으로는 변경할 수 없습니다 Collections.unmodifiableList(). 작은 목록을 얻으려는 경우 이것이 가장 좋은 방법이지만 다른 컬렉션의 경우 투명성이 떨어지므로 -a를 만들기 전에 Set목록을 만들어야 합니다 . 그러나 이것이 이중 중괄호 초기화보다 더 낫습니다. 이 경우 추가 내부 익명 클래스가 사용될 때마다 생성되지 않기 때문입니다. Java 8을 실행하는 경우 다른 대체 방법이 있습니다. JDK 8 Stream API는 출력 방법을 컬렉션으로 결합하여 작은 컬렉션을 만드는 데 도움이 됩니다 . ListSetStream FactoryList
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
대신 아래와 같이 방법을 Set사용할 수 있습니다 . Collectors.toSet()Collectors.toList()
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
그런데 Stream collect메서드는 자신이 생성한 컬렉션이 변경되지 않도록 보호한다고 보장하지 않습니다. Java 8에서 반환된 컬렉션(예: - ArrayList, HashSetHashMap)은 매우 일반적이지만(변경 가능) 이 사실은 향후 JDK 릴리스에서 수정될 수 있습니다. Double brace지금은 Java 초기화에 대한 모든 것입니다 . 이 템플릿은 테스트 및 데모에는 적합하지만 프로덕션 용도로는 충분하지 않습니다. 본질적인 단점으로 인해 이중 중괄호 초기화는 요즘 특히 사용 가능한 대안이 있는 경우 안티 패턴이 되었습니다. 나 자신은 여전히 ​​이 구성을 사용하여 정적 맵을 초기화하고 그게 전부입니다. List나는 생성자에서 Collections생성과 결합하여 생성하는 것을 선호 합니다 . Array.asList그리고 Java 8을 사용하는 경우 Stream API와 collect(). 관련 기사: 이 튜토리얼이 마음에 들었고 Java 프로그래밍 패턴, 원칙, 모범 사례에 대해 자세히 알아보고 싶다면 당사 사이트 의 다른 기사도 확인해 보세요 . 추천 도서: 패턴과 모범 사례에 대해 더 자세히 알아보려면 Joshua Bloch의 효과적인 프로그래밍을 읽어보세요 . 그 어떤 책도 대신할 수 없습니다. 그리고 이미 자바에 능숙하고, 유머러스한 표현 방식과 읽기 쉬운 디자인 패턴에 관한 책을 찾고 있다면, 『Head First. 디자인 패턴" .
번역자 의견: 러시아어로의 번역이 실패했기 때문에 의도적으로 Bloch의 원본 책에 대한 링크를 제공했습니다(예: Builder = constructor).
기사 번역 Java에서 이중 중괄호 초기화란 무엇입니까? 안티 패턴 예제 (2015년 10월 게시).
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION