[Effective Java] 22. 멤버 클래스는 가능하면 static으로 선언하라.

2 분 소요

중첩 class(nested class)에는 4가지 종류가 있다. 이 4가지 중첩 클래스에 대해 알아본다.

1. static member class

정적 멤버 클래스.
static member class는 바깥 클래스의 static 멤버이며, 다른 static 멤버와 동일한 접근 권한 규칙을 갖는다.

그냥 어쩌다 다른 클래스 안에 선언된 일반 클래스라고 보면 된다.

1.1. 자주 사용되는 패턴

  1. Helper class
    static member class는 바깥 클래스와 함께 사용할때 유용한 Helper class를 만들때 자주 사용된다.
    예를 들어 객체를 생성하는 Builder를 만드는것도 생성하려는 class의 static member class로 만드는 경우가 많다.

  2. 객체의 컴포넌트 표현
    private static member class를 주로 사용 하는 패턴으로 객체 컴포넌트로 사용하는 경우가 있다.
    예를 들어 해당 class 내부에서 어떤 값을 저장하는데 key, value 쌍이 필요하다. 이런 경우 이 class는 내부에서만 사용되고 바깥 class의 멤버를 사용할 일이 없을 것이므로 private static member class로 사용 가능하다.

2. non-static member class

비정적 멤버 클래스.
문법적으로는 static을 붙이느냐 아니냐의 차이지만 내부 구현의 차이는 크다.

non-static 멤버이기 때문에 바깥 클래스 객체 없이는 존재할 수 없다.
즉, 바깥 클래스 객체와 자동으로 연결된다는 것이고 이로 인해 바깥 클래스의 메서드도 호출할 수 있다. 또한 this 한정 구문을 통해 바깥 객체의 참조를 획득할 수도 있다.

아래는 this 한정 구문을 사용한 예이다.

class Envelope{
	void x() { ... }
	class Enclosure {
		void x() {
			Envelope.this.x();	// this 한정 구문
		}
	}
}

2.1. 자주 사용되는 패턴

non-static 멤버 클래스는 Adapter를 정의할 때 많이 사용된다.

2.2. 가능한 static member class로 만들자.

바깥 클래스 객체에 접근이 필요가 없는 멤버 클래스를 정의할때는 항상 static member class로 만들자.

non-static 멤버 클래스로 만들 경우 바깥 객체에 대한 참조가 유지된다. 이때문에 객체 생성 시간과 메모리 요구량이 늘어나고 바깥 객체에 대한 GC가 어려워 진다.

3. anonymous class

익명 클래스.
이름 없이 사용하는 순간에 선언하고 객체를 만든다.
표현식 문법만 준수하면 코드 어디서든 사용할 수 있다.

익명 클래스는 non-static context 안에서 사용될때만 바깥 객체를 사용할 수 있다. 하지만 static context 안에서 사용된다고 해도 class 내부에 static 멤버를 가질 수는 없다.

3.1. 제약사항

anonymous class는 제약사항이 많다.

  1. 선언하는 순간에만 객체를 만들 수 있다.
  2. instanceof처럼 클래스 이름이 필요한 곳에서는 사용할 수 없다.
  3. 여러 interface를 구현하는 익명 클래스는 선언할 수 없다.
  4. class 상속과 interface 구현을 동시에 하는 클래스에 대한 익명 클래스를 만들 수 없다.

4. local class

지역 클래스.
네가지 중첩 클래스 중 사용빈도가 가장 낮다. 지역 변수가 선언될 수 있는 곳이라면 어디서든 지역 클래스를 선언할 수 있고, 지역변수와 동일한 유효범위를 갖는다.

member class 처럼 이름을 가지고 반복적으로 사용될 수 있다. anonymous class 처럼 non-static context 안에서 사용될때만 바깥 객체를 사용할 수 있고 static context 안에서 사용된다고 해도 class 내부에 static 멤버를 가질 수 없다.

댓글남기기