티스토리 뷰
(Effective Java) 규칙24. 멤버 클래스는 되도록 static으로 만들라
중첩 클래스
중첩 클래스(nested class)란 다른 클래스 안에 정의된 클래스를 말한다.
- 자신을 감싼 바깥 클래스에서만 쓰여야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 함
중첩 클래스의 종류
아래 중 첫번째를 제외한 나머지는 모두 내부 클래스(inner class)에 해당한다.
정적 멤버 클래스
다른 클래스 안에 선언되고, 바깥 클래스의
private
멤버에도 접근할 수 있다.- 그 외에는 일반 클래스와 동일하다.
다른 정적 멤버와 똑같은 접근 규칙을 적용 받는다.
private
으로 선언하면 바깥 클래스에서만 접근할 수 있음
흔히 바깥 클래스와 함께 쓰일 때만 유용한
public
도우미 클래스로 쓰인다.- 예) 계산기가 지원하는 연산 종류를 정의하는 열거 타입 (규칙 34)
Operation
열거 타입은Calculator
클래스의public
정적 멤버 클래스가 되어야 함- 그러면
Calculator
클라이언트에서Cacluator.Operation.PLUS
나Calculator.Operation.MINUS
같은 형태로 연산을 참조할 수 있음
- 예) 계산기가 지원하는 연산 종류를 정의하는 열거 타입 (규칙 34)
정적, 비정적 멤버 클래스의 구문상 차이는 단지
static
이 붙어 있고 없고 차이지미나 의미상 차이는 의외로 크다.- (비정적) 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결되어 정규화된
this
를 사용해 바깥은 참조 가능함- 정규화된
this
란클래스명.this
형태로 바깥 클래스의 이름을 명시하는 용법
- 정규화된
- 따라서, 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적 멤버 클래스로 만들어야 함
- (비정적) 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결되어 정규화된
비정적 멤버 클래스
-
바깥 인스턴스 사이의 관계는 멤버클래스가 인스턴스화될 때 확립되며, 더 이상 변경할 수 없다.
- 보통 바깥 클래스의 인스턴스 메서드에서 비정적 멤버 클래스의 생성자를 호출 할 때 자동으로 만들어짐
- 드물게는 바깥 인스턴스의
클래스.new Member Class(args)
를 호출해 수동으로 만들기도 함- 다만, 멤버 클래스의 인스턴스 안에 만들어져 메모리 공간을 차지하며, 생성 시간도 오래 걸림
-
어탭터를 정의할 때 자주 쓰인다.
- 즉, 어떤 클래스의 인스턴스를 감싸 마치 다른 클래스의 인스턴스처럼 보이게 하는 뷰로 사용하는 것
-
Map
인터페이스의 구현체들은 보통(keySet
,entrySet
,values
메서드가 반환하는) 자신의 컬렉션 뷰를 구현할 때 비정적 멤버 클래스를 사용함 -
Set
과List
같은 컬렉션 인터페이스 구현들도 자신의 반복자를 구현할 때 비정적 멤버 클래스를 주로 사용함public class MySet<E> extends AbstractSet<E> { ... // 생략 @Override public Iterator<E> iterator() { return new MyIterator(); } private class MyIterator implements Iterator<E> { ... } }
-
멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건
static
을 붙여서 정적 멤버 클래스로 만들자.static
을 생략하면 바깥 인스턴스로의 숨은 외부 참조를 갖게 됨- 참조를 저장하려면 시간과 공간이 소비되며 가비지 컬렉션이 바깥 인스턴스를 수거하지 못하는 메모리 누수가 생길수 있음(규칙 7)
private 정적 멤버 클래스 (정적 멤버의 특이 케이스🤘)
- 흔히 바깥 클래스가 표현하는 클래스가 표현하는 객체의 한 부분(구성요소)을 나타낼 때 쓴다.
- 예) 키와 값을 매핑시키는
Map
인스턴스- 많은
Map
구현체는 각각의 키-값 쌍을 표현하는Entry
객체들을 가지고 있음 - 모든
Entry
가 맴과 연관되어 있지만 메서드들(getKey
,getValue
,setValue
)은 맵을 직접 사용하지는 않음 - 따라서,
Entry
를 비정적 멤버 클래스로 표현하는 것은 낭비고,private
정적 멤버 클래스가 가장 알맞음
- 많은
- 예) 키와 값을 매핑시키는
- 멤버 클래스가 공개된 클래스의
public
이나protected
멤버라면 정적이냐 아니야가 더욱 중요해진다.- 멤버 클래스 역시 공개 API가 되니, 혹시라도 향후 릴리스에서
static
을 붙이면 하위 호환성이 깨짐
- 멤버 클래스 역시 공개 API가 되니, 혹시라도 향후 릴리스에서
익명 클래스
멤버와 달리 쓰이는 시점에 인스턴스가 만들어진다. (코드의 어디서든 만들 수 있음)
오직 비정적인 문맥에서 사용될 떄만 바깥 클래스의 인스턴스를 참조할 수 있다.
- 정적 문맥에서라도 상수 변수 이외의 정적멤버는 가질 수 없음
- 상수 표현을 위해 초기화된
final
기본 타입과 문자열 필드만 가질 수 있음
익명 클래스는 응용하는데 제약이 많은 편이다.
- 선언한 지점에서만 인스턴스를 만들 수 있음
instanceof
검사나 클래스의 이름이 필요한 작업은 수행할 수 없음- 여러 인터페이스를 구현할 수 없고, 인터페이스를 구현하는 동시에 다른 클래스를 상속할 수도 없음
- 익명 클래스를 사용하는 클라이언트는 익명 클래스가 상위 타입에서 상속한 멤버 외에는 호출할 수 없음
- 익명 클래스는 표현식 중간에 등장하므로 (10줄 이하로) 짧지 않으면 가독성이 떨어짐
익명 클래스의 또 다른 주 쓰임은 정적 팩터리 메서드를 구현할 때다.
지역 클래스
종류 중 가장 드물게 사용된다.
지역변수를 선언할 수 있는 곳이면 실질적으로 어디서든 선언할 수 있고, 유효 범위도 지역변수와 같다.
다른 세 중첩 클래스와의 공통점도 하나씩 가지고 있다.
- 멤버 클래스처럼 이름이 있고 반복해서 사용할 수 있음
- 익명 클래스처럼 비정적 문맥에서 사용될 때만 바깥 인스턴스를 참조할 수 있음
- 정적 멤버는 가질수 없으며, 가독성을 위해 짧게 작성해야 함
결론
중첩 클래스에는 네 가지가 있으며, 각각의 쓰임이 다른다.
- 메서드 안에 정의하기엔 너무 길다면 멤버 클래스
- 멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적, 그렇지 않으면 정적
- 중첩 클래스가 한 메서드 안에서만 쓰이면서 인스턴스를 생성하는 지점이 단 한 것이고 해당 타입으로 쓰기에 적합한 인터페이스가 있다면 익명 클래스
- 그렇지 않으면 지역 클래스
끝으로
이 글이 도움이 되었다면, 하단의 Google 광고 👎👎👎 한번씩 클릭 부탁 드립니다. 🙏🙏🙏
광고 클릭은 많은 힘이 됩니다!
'프로그래밍 > EffectiveJava' 카테고리의 다른 글
(이펙티브 자바) 규칙23. 태그달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2020.03.26 |
---|---|
(이펙티브 자바) 규칙25. 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2020.03.15 |
(이펙티브 자바) 규칙26. 로 타입은 사용하지 말라 (0) | 2020.03.13 |
(이펙티브 자바) 규칙63. 문자열 연결은 느리니 주의하라 (0) | 2020.03.12 |
(이펙티브 자바) 규칙64. 객체는 인터페이스를 사용해 참조하라 (0) | 2020.03.11 |
- Total
- Today
- Yesterday
- 텐트
- 일본 자전거 여행
- 방통대 과제물
- JavaFX Window Close
- intelij
- effectivejava
- 이펙티브
- JavaFX
- 배낭여행
- 자전거 여행
- windows
- JavaFX Table View
- JavaFX 테이블뷰
- 인텔리제이
- 스프링부트
- java
- 일본 배낭여행
- Java UI
- 일본여행
- JavaFX 종료
- git
- 자전거
- effective java
- 이펙티브자바
- 자바
- springboot
- 일본 여행
- 이펙티브 자바
- TableView
- 배낭 여행
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |