중첩 클래스에는 네가지 종류가 있는데, static 맴버 클래스, static이 아닌 맴버 클래스, 익명 클래스, 지역클래스이다. 이 모두를 내부클래스(inner class)라고 한다.
구문적으로 봐선 static과 static이 아닌 맴버 클래스의 유일한 차이점은, static 맴버 클래스의 선언부에 static 수식어가 있다는 것이다. 간단한 예를 들면 이런 것이다.
static 맴버 클래스 | static이 아닌 맴버 클래스 |
public class A{ private a; static class A_1{ } static class A_2{ } } |
public class A{ private a; class A_1{ } class A_2{ } } |
구문적으로는 유사하지만 이 두 종류의 중첩 클래스는 많이 다른다.
static이 아닌 멤버 클래스의 각 인스턴스는 자신을 포함하는 외곽 클래스의 인스턴스와 은연 중에 연관이 된다. 따라서 static이 아닌 멤버 클래스의 인스턴스 메소드 내부에서 외곽 클래스의 인스턴스 메소드를 호출하거나, 또는 this 키워드를 사용해서 외곽 클래스의 인스턴스에 대한 참조를 얻을 수 있다.
private static맴버 클래스의 경우 외곽클래스를 나타내는 객체 컴포넌트 표현에 사용하는데 적합다. 불필요하게 외부에 객체 참조를 제공하지 않아 리소스 낭비가 없어진다.
만일 외곽 클래스의 인스턴스를 사용할 필요가 없는 멤버 클래스를 선언한다면, 항상 static 수신자를 선언부에 추가하여 static 맴버 클래스로 만들자.
익명 클래스는 함수 객체를 생성하는데 많이 사용된다. 또한 Runnalbe, Thread, TimerTask 등의 인스턴스와 같은 프로세스 객체를 생성하는데도 많이 사용한다. 그리고 static 팩토리 메소드 내부에서도 사용된다.
지역클래스는 지역 변수가 선언 될 수 있는 곳이면 어디든 선언될 수 있으며, 지역 변수와 동일한 유효 범위를 갖는다. 또한 다른 종류의 중첩 클래스와 동일한 속성을 갖는다. 맴버 클래스처럼 이름을 가질 수 있어 반복적으로 사용될 수 있으며 static이 아닌 상황일 때에 한해서 익명 클래스 처럼 외곽 인스턴스를 가지며 static 멤버를 포함할 수 없다.
만일 중첩 클래스가 메소드 외부에서 접근할 필요가 있거나 코드가 너무 길어서 메소드 내부에 두기 적합하지 않다면 멤버 클래스를 사용하자. 만일 멤버 클래스의 각 인스턴스가 외곽 클래스의 인스턴스를 참조할 필요가 있다면 static 이 아닌 멤버 클래스로 만들고 그렇지 않다면 static으로 만든다. 클래스가 어떤 메소드 내부에 속한다는 가정하에, 만일 한 곳에서만 그 클래스의 인스턴스를 생성할 필요가 있고 그 클래스의 특성을 나타내는 타입이 이미 존재한다면, 익명 클래스로 만들고 그렇지 않으면 지역클래스로 만든다.
'개발 이야기 > Effective Java' 카테고리의 다른 글
Item 21. 전략을 표현할 때 함수 객체를 사용하자. (0) | 2010.03.22 |
---|---|
Item 23. 새로 작성하는 코드에서는 원천(raw) 타입을 사용하지 말자. (0) | 2010.03.22 |
Item 24. 컴파일 경고 메시지가 없게 하자. (0) | 2010.03.22 |
Item 10. toString 메소드는 항상 오버라이드 하자. (0) | 2010.03.11 |
Item 9. equals 메소드를 오버라이드 할 때는 hashcode 메소드도 항상 같이 오버라이드 하자. (0) | 2010.03.11 |