중첩 클래스(nested class)란 다른 클래스 안에 정의된 클래스를 말한다. 자신을 감싼 바깥 클래스에서만 쓰여야 한다. 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다.
중첩 클래스의 종류
- 정적 멤버 클래스
- (비정적) 멤버 클래스
- 익명 클래스
- 지역 클래스
정적 멤버 클래스를 제외한 나머지 3가지가 내부 클래스(inner class)에 해당한다.
정적 멤버 클래스와 비정적 멤버 클래스는 구문상 차이는 단지 static이 붙어 있고의 차이뿐이지만, 의미상 차이는 꽤 크다.
비정적 멤버 클래스 인스턴스 생성
public class Outer {
private int a;
class inner {
private int b;
}
}
Outer outer = new Outer();
Outer.inner inner = outer.new inner();
// or
Outer.inner inner1 = new Outer().new inner();
비정적 멤버 클래스의 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결되 있는 특징이 있다.
개념상에 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적 멤버 클래스로 만들어야 한다.
이러한 비정적 멤버 클래스를 생성하는데 해당 인스턴스 안에 만들어져 메모리 공간을 차지하며, 생성 시간도 더 걸린다.
비정적 멤버 클래스는 어댑터를 정의할 때 자주 쓰인다
- 어떤 클래스의 인스턴스를 감싸 마치 다른 클래스의 인스턴스처럼 보이게 하는 뷰로 사용
멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.
- static을 생략하면 바깥 인스턴스로의 숨은 외부 참조를 갖게 된다.
- 이 참조를 저장하려면 시간과 공간이 소비된다.
- gc가 바깥 클래스의 인스턴스를 수거하지 못해 메모리 누수가 발생한다.
익명 클래스
- 이름이 없다.
- 바깥 클래스의 멤버도 아니다.
- 쓰이는 시점에 선언과 동시에 인스턴스가 만들어진다.
- 오직 비정적인 문맥에서 사용될 때만 바깥 클래스의 인스턴스를 참조할 수 있다.
- 상수 표현을 위해 초기화된 final 기본 타입과 문자열 필드만 가진다.
익명 클래스의 제약
- instanceof 검사나 클래스의 이름이 필요한 작업은 수행할 수 없다.
- 여러 인터페이스를 구현할 수 없고, 인터페이스를 구현하는 동시에 다른 클래스를 상속할 수도 없다.
- 익명 클래스를 사용하는 클라이언트는 그 익명 클래스가 상속한 상위 타입의 멤버 외에는 호출 할 수 없다.
- 코드가 간결하면 가독성이 좋으나 길어지면 가독성이 떨어진다.
지역 클래스
- 지역변수와 같은 유효 범위를 갖는다.
- 멤버 클래스처럼 이름이 있고 반복해서 사용할 수 있다.
- 비정적 문맥에서 사용될 때만 바깥 인스턴스를 참조할 수 있다.
- 정적 멤버는 가질 수 없다.
- 가독성을 위해 간결하게 작성해야한다.
정리
- 메서드 밖에서도 사용해야 하거나 메서드 안에 정의하기엔 너무 길다면 멤버 클래스로 만든다.
- 멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적으로, 그렇지 않으면 정적으로 만들자.
- 중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한 곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있다면 익명 클래스로 만들고, 그렇지 않으면 지역 클래스로 만들자.
'Book > Effective Java' 카테고리의 다른 글
[Item 28] 배열보다는 리스트를 사용하라 (0) | 2022.08.18 |
---|---|
[Item 27] 비검사 경고를 제거하라 (0) | 2022.08.06 |
[Item 26] 로 타입(Raw Type)은 사용하지 말라 (0) | 2022.08.05 |
[Item 25] 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2022.08.05 |
[Item 23] 태그 달린 클래스보다 클래스 계층구조를 활용하라 (0) | 2022.07.27 |
[Item 22] 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.07.26 |
[Item 21] 인터페이스는 구현하는 쪽을 생각해 설계해라 (0) | 2022.07.26 |
[Item 20] 추상 클래스보다는 인터페이스를 우선하라 (0) | 2022.07.26 |