참조: Effective Java 2nd Edition. Item 22: Favor static member class over nonstatic


중첩 클래스(nested class)에는 네 종류가 있다.
- static member class
- nonstatic member class
- anonymous class
- local class

Static Member Class

public class SpringSprout {
   static class Whiteship {
        private String name; 
        ...
    }
}

- 다른 클래스 내부에 선언된 클래스로 가장 많이 사용된다.
- 자신을 가지고 있는 클래스의 모든 멤버에 접근할 수 있다.
- 보통 helper 클래스로 사용된다.
- enclosing instance 유무와 상관없이 독립적으로 사용될 수 있다.

Nonstatic Member Class

public class SpringSprout {
   class Whiteship {
        private String name; 
        ...
    }
}


- 암묵적으로 자신을 감싸는 클래스의 인스턴스(enclosing instance)와 연관을 맺는다.
- nontatic member class와 enclosing instance와의 연관 관계는 enclosing instance에서 nonstatic member class의 객체를 만들 때 생긴다.
- 이 연관 관계로 인해 nonstatic member class 인스턴에 필요한 공간과 생성 시간이 소비된다.
- 보통 Adapter를 정의할 때 사용된다.
- Map의 keySet, entrySet, values 메서드가 반환하는 콜렉션 뷰들과 Set, List에서 Iterator를 구현할 때 nonstatic member class를 사용한다.

AbstractList 코드

    public Iterator<E> iterator() {
return new Itr();
    }
    private class Itr implements Iterator<E> {
    ...
    }

=> enclosing instance에 접근할 필요가 없는 member class는 static으로 선언하자.

Anonymous Class
- 이름도 없고 enclosing class의 멤버도 아니다.
- 표현식을 사용할 수 있는 곳이라면 어디서든 익명 클래스를 사용할 수 있다.
- nonstatic 문맥에서만 enclosing instance를 가진다.
- static 문맥에서는 static 멤버를 가질 수 없다.
- 주로 함수 객체를 만들 때 사용한다.

Local Class
- 익명 클래스랑 거의 같은데 클래스 이름 줄 수 있고 인스턴스 여러 번 만들어 사용할 수 있다.
- 걍 생략;

요약
- 중첩 클래스가 특정 메서드 외부에서도 사용될 피룡가 있거나 메서드 내부에 있기에는 너무 길다면 멤버 클래스로 만든다.
- 만약 멤버 클래스의 인스턴스가 enclosing instance를 참조할 필요가 있다면 nonstatic으로 만든다. 그렇지 않으면 static으로 만든다.
- 클래스가 메서드 내부에 속해 있으며 딱 한번만 사용할거면 익명 클래스로 만들고, 그렇지 않으면 로컬 클래스로 만든다.