본문은 Effective Java를 읽고 정리한 내용을 기반으로 작성된 글입니다.
☑️ 중첩 클래스(nested class)
: 다른 클래스 안에 정의된 클래스 ↔ 자신을 감싼 바깥 클래스에서만 쓰여야함
- 정적 멤버 클래스
- 비정적 멤버 클래스
- 익명 클래스
- 지역 클래스
정적 멤버 클래스를 제외한 나머지는 내부 클래스(inner class)에 해당된다.
[정적 멤버 클래스 & 비정적 멤버 클래스]
☑️ 정적 멤버 클래스
: 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다
- 외부 클래스와 독립적으로 존재할 수 있음 → 외부 클래스의 인스턴스에 종속되지 않음 (inner class로 간주되지 않는 이유)
☑️ 비정적 멤버 클래스
- 구문상으로는 static 있고 없고 차이지만, 비정적 멤버 클래스의 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결됨 → 바깥 인스턴스로의 숨은 외부 참조를 갖게된다
- 비정적 멤버 클래스의 인스턴스 메서드에서 정규화된 this를 사용 → 바깥 인스턴스의 메서드 호출, 바깥 인스턴스의 참조를 가져올 수 있음
- 정규화된 this : 클래스명.this 형태로 바깥 클래스의 이름을 명시하는 용법
- 멤버 클래스가 공개된 클래스의 public이나 protected멤버라면 정적 or 비정적이 두 배로 중요해짐
→ 멤버 클래스 역시 공개 API가 되어 향후 릴리즈에서 static을 붙이면 하위 호환성이 깨지기 때문
ex) Map 구현체
- 많은 Map 구현체는 각각의 키-값 쌍을 표현하는 Entry 객체를 가짐
- 모든 엔트리가 맵과 연관되어 있지만, 엔트리의 메서드들(getKey, setValue등)은 맵을 직접 사용하지는 않음
→ 바깥 맵으로의 참조가 필요 없는 상황 → 엔트리를 비정적 멤버 클래스로 표현하는 것은 메모리 공간, 생성 시간 낭비
☑️ 결론
: 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재 가능 → 정적 멤버 클래스로 만들어야 한다
☑️ 그러면 비정적 멤버 클래스는 언제 쓰일까
: 어댑터(어떤 클래스의 인스턴스를 감싸 마치 다른 클래스의 인스턴스처럼 보이게 하는 뷰)를 정의할 때 자주 쓰임
ex) Map 인터페이스의 구현체
public class HashMap<K, V> extends AbstractMap<K, V>
implements Map<K, V>, Cloneable, Serializable {
final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
// size(), clear(), contains(), remove(), ...
}
final class KeySet extends AbstractSet<K> {
// size(), clear(), contains(), remove(), ...
}
final class Values extends AbstractCollection<V> {
// size(), clear(), contains(), remove(), ...
}
}
→ keySet(), entrySet(), values()가 반환하는 자신의 컬렉션 뷰를 구현할 때 활용 가능
[익명 클래스]
: 쓰이는 시점에 선언과 동시에 인스턴스가 만들어지는 클래스
- 자바가 람다를 지원하기 전에 익명 클래스를 주로 사용했다
[지역 클래스]
: 드문 사용, 지역변수처럼 선언하여 사용하는 클래스
[핵심 정리]
중첩 클래스에는 네 가지가 있으며, 각각의 쓰임이 다르다.
- 메서드 밖에서도 사용해야 하거나 메서드 안에 정의하기엔 너무 길다면 멤버 클래스로 만든다.
- 멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적 클래스로, 그렇지 않으면 정적 클래스로 만들자.
- 중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한 곳이며, 해당 타입으로 쓰기에 적합한 클래스나 인터페잏스가 이미 있다면 익명 클래스로 만들자.
- 그렇지 않다면 지역 클래스로 만들자.
'Book > 이펙티브 자바' 카테고리의 다른 글
[Effective Java] item 25. 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2023.12.23 |
---|---|
[Effective Java] item 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2023.12.23 |
[Effective Java] item 21+22. 인터페이스는 구현하는 쪽을 생각해 설계하라, 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2023.12.22 |