Effective Java 3rd ITEM 24
ITEM 24. Favor static member classes over nonstatic
중첩 클래스는 다른 클래스 안에 정의된 클래스를 말한다. 자신을 감싼 바깥 클래스에서만 쓰여야 하며 그 외로 쓰인다면 톱레벨 클래스로 작성해야 한다.
정적 멤버 클래스
정적 멤버 클래스는 다른 클래스 안에 선언되어있는 점과 바깥 클래스의 private 멤버에 접근할 수 있다는 점을 제외하고는 보통의 클래스와 같다.
정적 멤버 클래스는 바깥 클래스와 함께 쓰일 때만 유용한 public 클래스로 쓰인다.
비정적 멤버 클래스
비정적 멤버 클래스의 가장 큰 특징은 바깥 클래스의 인스턴스에 비정적 멤버 클래스의 인스턴스가 연결되어있다는 점이다. 그래서 바깥 클래스명.this
형태로 바깥 인스턴스의 메서드를 호출할 수 있다.
따라서 비정적 멤버 클래스는 바깥 인스턴스 없이는 생성할 수 없기 때문에, 바깥 인스턴스와 멤버 클래스가 독립적이라면 정적 멤버 클래스로 작성해야 한다.
비정적 멤버 클래스의 인스턴스와 바깥 인스턴스 사이의 관계는 멤버 클래스 인스턴스가 생길 때 멤버 클래스 인스턴스 안에 만들어진다. 이 때문에 메모리 공간을 차지하게 되고 생성 시간 또한 더 걸린다. 비정적 멤버 클래스로 작성하면 바깥 인스턴스의 숨은 외부 참조를 갖게 되면서 가바지 컬렉션이 바깥 인스턴스를 수거하지 못하는 경우도 발생할 수 있다.
따라서 멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건 정적 멤버 클래스로 작성하자.
익명 클래스
익명 클래스는 바깥 클래스의 멤버가 아니다. 쓰이는 시점에 선언과 동시에 인스턴스도 만들어진다. 또 비정적인 문맥에서 사용될 때만 바깥 클래스의 인스턴스를 참조할 수 있다. 정적 문맥에서라도 상수 변수 이외의 정적 멤버는 가질 수 없다.
익명 클래스는 여러 인터페이스를 구현할 수 없고 인터페이스를 구현하는 동시에 다른 클래스를 상속할 수도 없다. 클래스 이름이 필요한 instanceof 검사도 수행할 수 없다.
Lambda가 나오기 전에 작은 함수 객체나 처리 객체를 만드는데 익명 클래스가 많이 쓰였다.
지역 클래스
지역변수를 선언할 수 있는 곳이면 실질적으로 어디서든 선언할 수 있다. 유효 범위도 지역변수와 같다. 멤버 클래스처럼 이름이 있고 반복 사용 가능하고, 익명 클래스처럼 비정적 문맥에서 사용될 때만 바깥 인스턴스를 참조할 수 있고, 정적 멤버는 가질 수 없다.