April 10th, 2007
Anonymous Class 초기화 하기 - Instance initializer

간만에 자바 관련 포스팅인듯.
Java의 Anonymous class는 클래스의 작명과정을 거치지 않고 subclassing과 instancing을 한 큐에 처리해 주어서 event handler 등에서 많이 쓰인다.

그런데 익명 클래스는 생성자를 재정의 할 수가 없다. 예를 보자.

JAVA:
  1. JFrame frame = new JFrame("Anonymous class initializer");
  2. frame.add(new JButton("Call-151") {
  3. });

위의 예는 JButton을 상속받는 Anonymous class를 만들었다(하는 일은 없지만)..
흠..예가 딱히 좋지는 않다.

저 버튼의 배경색을 바꾸고 싶으면 물론 버튼을 변수에 할당하고 bt.setBackground()를 호출하면 된다.
하지만 어떤 이유로인해 익명 클래스로 써야 한다면?

마음은 이렇게 하고 싶다.

JAVA:
  1. JFrame frame = new JFrame("Anonymous class initializer");
  2. frame.add(new JButton("Call-151") {
  3.    public this(String title) {
  4.       super(title);
  5.       setBackground(Color.BLUE);
  6.    }
  7. });

하지만 이런 문법은 지원하지 않는다.
대신 이렇게 한다.

JAVA:
  1. frame.add(new JButton("Call-151") {
  2. {
  3.     setBackground( Color.BLUE );
  4. }
  5. });

이는 Instance initializer라는 기능을 사용한 것이다.
많은 개발자들이 static initializer는 마땅한 workaround가 없어서 잘 인지하고 있지만 instance initializer는 잘 모른다(몰라도 사는데 지장이 없다)

이놈은 객체가 생성되는 시점에 호출된다는 점에서 생성자와 같지만 시점이 좀 다르다.
그리고 꼭 Anonymous class에서만 지원되는 것도 아니다(하지만 그 외의 경우는 쓸 일이 없다..^^)

호출 시점은 super class의 생성자와 현재 클래스의 생성자 사이에 발생한다.

JAVA:
  1. public class InstanceInit {
  2.     private static class SubInstanceInit extends InstanceInit {
  3.         {
  4.             System.err.println("[SubInstanceInit.instance initializer]");
  5.         }
  6.  
  7.         public SubInstanceInit() {
  8.             System.err.println("[SubInstanceInit()]");
  9.         }
  10.     }
  11.  
  12.     public InstanceInit() {
  13.         System.err.println("[InstanceInit()]");
  14.     }
  15.  
  16.     public static void main(String[] args) {
  17.         new SubInstanceInit();
  18.     }
  19. }

이 결과는 요모양이다.

[InstanceInit()]
[SubInstanceInit.instance initializer]
[SubInstanceInit()]