본문 바로가기
Java

[Java] 이중 중괄호 초기화 (Anti-pattern)

by 굿햄 2022. 12. 29.

자바 이중 중괄호 초기화 (Anti-pattern)

Unsplash: uploaded by @cookiethepom

Kotlin의 Scope function과 같은 느낌이라 변수 초기화에 괜찮은 듯 보이는데,
잘 알려지지 않았고 흔히 사용하지 않는다고 한다

개인적으로는 Java고유의 문법 스타일에 의한 관례인가 했으나
개발자의 실수로 인한 치명적인 문제들이 있다.

1. 과도한 Anonymous class 생성

함수 내에서 이중 중괄호 내에 new를 사용할 수록, 익명 클래스의 개수가 늘어난다.

Map source = new HashMap(){{
    put("firstName", "John");
    put("lastName", "Smith");
    put("organizations", new HashMap(){{
        put("0", new HashMap(){{
            put("id", "1234");
        }});
        put("abc", new HashMap(){{
            put("id", "5678");
        }});
    }});
}};

// 생성된 익명 클래스
Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class

2. 메모리 릭 발생

함수 내에 this는 해당 메소드를 포함한 클래스를 들고 있어야한다.
문제는 아래와 같이 코드 내에서 클래스를 들고 있을 필요가 없을 때이다.

public class ReallyHeavyObject {
 
    // Just to illustrate...
    private int[] tonsOfValues;
    private Resource[] tonsOfResources;
 
    // This method almost does nothing
    public void quickHarmlessMethod() {
        Map source = new HashMap(){{
            put("firstName", "John");
            put("lastName", "Smith");
            put("organizations", new HashMap(){{
                put("0", new HashMap(){{
                    put("id", "1234");
                }});
                put("abc", new HashMap(){{
                    put("id", "5678");
                }});
            }});
        }};
         
        // Some more code here
    }
}


// 사용 예제
public static void main(String[] args) throws Exception {
    Map map = new ReallyHeavyObject().quickHarmlessMethod();
    Field field = map.getClass().getDeclaredField("this$0");
    field.setAccessible(true);
    System.out.println(field.get(map).getClass());
}

// ReallyHeavyObject는 사라지지 않는다.

ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.

댓글