중첩 클래스는 다른 클래스 안에 정의된 클래스다. 중첩 클래스는 해당 클래스가 속한 클래스 안에서만 사용된다. 그렇지 않으면 중첩클래스를 만들면 안된다.
정적 멤버 클래스
정적 멤버 클래스는 바깥 클래스의 모든 멤버(private 포함)에 접근할 수 있다. 정적 멤버 클래스는 바깥 클래스의 정적 멤버이며, 다른 정적 멤버와 동일한 접근 권한 규칙을 따른다. 바깥 클래스와 함께 사용할 때만 유용한 public 도움 클래스를 정의할 때 유용하다. 예를 들어 계산을 책임지는 클래스안의 사칙 연산을 나타내는 enum클래스같은 경우가 있다.
비-정적 멤버 클래스
비-정적 멤버 클래스 객체는 바깥 클래스 객체와 자동적으로 연결된다. 바깥 클래스 객체와 독립적으로 존재할 수 있도록 하려면 정적 멤버 클래스로 선언해야 한다. 비-정적 멤버 클래스는 업댑터를 정의할 때 많이 사용하는 클래스이다. 바깥 클래스 객체를 다른 클래스 객체인 것처럼 보이게 하는 용도로 사용한다.
private 정적 멤버 클래스
바깥 클래스 객체의 컴포넌트를 표현하는 데 주로 쓰인다. 에를 들어, 키와 값을 연관 짓는 Map 객체를 보자. Map을 구현하는 많은 클래스는 내부적으로 키-값 쌍을 보관하는 Entry 객체를 사용한다. 각 Entry 객체는 특정 맵에 속할 것이지만, Entry 객체의 메서드(getKey,getValue ...) 는 맵 객체에 접근할 필요가 없다. 따라서 Entry를 비-정적 메서드로 표현하는 것은 낭비이며, private 정적 멤버 클래스로 정의하는 것이 최선이다.
why? Map객체를 여러 개 생성했을 때 비-정적 메서드로 정의되어 있지 않다면 모든 Map객체들이 Entry객체를 공유하게 될 것인데, Entry객체안의 key-value가 겹치게 되면 큰일이 나지 않나..? 이해가안된다..ㅠㅠ 나중에 다시 보도록하자!
익명 클래스
익명 클래스는 이름이 없다. 익명 클래스를 사용하는 데는 많은 제약이 있다. 선언하는 바로 그 순간에만 객체를 만들 수 있으며, instanceof를 비롯, 클래스 이름이 필요한 곳에는 사용할 수 없다. 또한 클래스가 길게 작성되면 가독성이 떨어지기도 한다.
이러한 익명 클래스는 함수 객체를 정의할 때 널리 쓰인다. 또한 Runnable, Thread 객체 같은 프로세스 객체를 만드는데도 널리 쓰인다.
지역 클래스
지역 클래스는 지역 변수가 선언될 수 있는 곳이라면 어디서든 선언할 수 있다.
요약
중첩 클래스에는 네 가지 종류가 있다. 중첩 클래스를 메서드 밖에서 사용할 수 있어야 하거나, 메서드 안에 놓기에 너무 길 경우에는 멤버 클래스로 정의하라. 멤버 클래스의 객체 각각이 바깥 객체에 대한 참조를 가져야 하는 경우에는 비-정적 멤버 클래스로 만들고, 그렇지 않은 경우에는 정적 멤버 클래스로 만들자. 중첩 클래스가 특정한 메서드에 속해야 하고, 오직 한곳에서만 객체를 생성하며, 해당 중첩 클래스의 특성을 규정하는 자료형이 이미 있다면 익명 클래스로 만들고 그렇지 않은 경우에는 지역클래스로 만들면 된다.
'개발서적 > 이펙티브자바' 카테고리의 다른 글
[제네릭]규칙24. 무점검 경고를 제거하라 (0) | 2017.04.27 |
---|---|
[제네릭]규칙23. 새 코드에는 무인자 제네릭 자료형을 사용하지마라. (0) | 2017.04.27 |
[클래스와 인터페이스]규칙21.전략을 표현하고 싶을 때는 함수 객체를 사용하라 (0) | 2017.04.26 |
[클래스와 인터페이스]규칙20. 태그달린 클래스 대신 클래스 계층을 활용하라 (0) | 2017.04.25 |
[클래스와 인터페이스]규칙19. 인터페이스는 자료형을 정의할 때만 사용하라 (0) | 2017.04.25 |