[Effective Java] 아이템 24. 멤버 클래스는 되도록 static으로 만들라

2022. 10. 4. 23:06· BE/Java
목차
  1. 아이템 24. 멤버 클래스는 되도록 static으로 만들라
  2.  
반응형

EFFECTIVE JAVA(이펙티브 자바)

 

 

이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.


아이템 24. 멤버 클래스는 되도록 static으로 만들라

 

중첩 클래스(nested class)

  • 중첩 클래스(nested class)란 다른 클래스 안에 정의된 클래스를 말한다.
  • 중첩 클래스는 자신을 감싼 바깥 클래스에서만 쓰여야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 한다.
  • 종류로는 정적 멤버 클래스, (비정적) 멤버 클래스, 익명 클래스, 지역 클래스
  • 위 중 첫 번째를 제외한 나머지는 내부 클래스(inner class)에 해당한다. 

 

 

정적 멤버 클래스

  • 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 똑같다.
    (다른 정적 멤버와 똑같은 접근 규칙을 적용받는다.)
  • 흔히 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스로 쓰임
    • 계산기가 지원하는 연산 종류를 정의하는 열거 타입을 예로 들면,
    • Operation 열거 타입은 Calculator 클래스의 public 정적 멤버 클래스가 되어야 한다.
    • 그러면 Calculator의 클라이언트에서 Calculator.Operation.PLUS or Calculator.Operation.MINUS처럼 사용 가능

 

 

비정적 멤버 클래스

  • 정적 멤버 클래스와 static이 붙어있고 없고의 차이.
  • 비정적 멤버 클래스의 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결됨
  • 비정적 멤버 클래스의 인스턴스 메서드에서 정규화된 this를 사용해 바깥 인스턴스의 메서드를 호출하거나 바깥 인스턴스의 참조를 가져올 수 있음
    • 정규화된 this? 클래스명.this 형태로 바깥 클래스의 이름을 명시하는 용법
  • 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적 멤버 클래스로 만들어야 함.
    비정적 멤버 클래스는 바깥 인스턴스 없이는 생성할 수 없기 때문
  • 비정적 멤버 클래스의 인스턴스와 바깥 인스턴스 사이의 관계는 멤버 클래스가 인스턴스화 될 때 확립되며, 더 이상 변경할 수 없음
  • 이 관계 정보는 비정적 멤버 클래스의 인스턴스 안에 만들어져 메모리 공간을 차지하며, 생성 시간도 더 걸린다.
  • 비정적 멤버 클래스는 어댑터를 정의할 때 자주 쓰임
    즉, 어떤 클래스의 인스턴스를 감싸 다른 클래스의 인스턴스처럼 보이게 하는 뷰로 사용
  • Map 인터페이스의 구현체들은 보통 자신의 컬렉션 뷰를 구현할 때 비정적 멤버 클래스를 사용
  • Set과 List 같은 다른 컬렉션 인터페이스 구현들도 자신의 반복자를 구현할 때 비정적 멤버 클래스를 주로 사용

 

ex 1) 비정적 멤버 클래스의 흔한 쓰임 - 자신의 반복자 구현

public class MySet<E> extends AbstractSet<E> {
    ... // 생략

    @Override 
    public Iterator<E> iterator() {
    	return new MyIterator();
    }

    private class MyIterator implements Iterator<E> {
    	...
    }
}

 

  • 멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.
  • static을 생략하면 바깥 인스턴스로의 숨은 외부 참조를 갖게 됨. (메모리 누수 발생 가능)

 

 

private 정적 멤버 클래스

  • 흔히 바깥 클래스가 표현하는 객체의 한 부분을 나타낼 때 사용
  • 키와 값을 매핑시키는 Map 인스턴스를 생각해보자.
    • 많은 Map 구현체는 각각의 키-값 쌍을 표현하는 엔트리 객체들을 가지고 있다.
    • 모든 엔트리가 Map과 연관되어 있지만, 엔트리 메서드들은 Map을 직접 사용하지 않아 엔트리를 비정적 멤버 클래스로 표현하는 것은 낭비이며 private 정적 멤버 클래스가 적절해보인다.

 

 

 

익명 클래스

  • 익명 클래스는 바깥 클래스의 멤버가 아니다. 
    멤버와 달리, 쓰이는 시점에 선언과 동시에 인스턴스가 만들어진다. (코드 어디에서든 만들 수 있으며, 비정적인 문맥에서 사용될 때만 바깥 클래스의 인스턴스를 참조할 수 있다.)
  • 정적 문맥에서라도 상수 변수 이외의 정적 멤버는 가질 수 없다.
    (상수 표현을 위해 초기화된 final 기본 타입과 문자열 필드만 가질 수 있음)
  • 응용하는데 제약이 많다.
    • 선언한 지점에서만 인스턴스를 만들 수 있고, instanceof 검사나 클래스의 이름이 필요한 작업은 수행 X
    • 여러 인터페이스를 구현할 수 없고, 인터페이스를 구현하는 동시에 다른 클래스 상속 불가
    • 익명 클래스를 사용하는 클라이언트는 그 익명 클래스가 상위 타입에서 상속한 멤버 외에는 호출 X
  • 자바가 람다를 지원하기 이전에는 즉석에서 작은 함수 객체나 처리 객체를 만드는 데 익명 클래스를 주로 사용함
  • 익명 클래스의 또 다른 주 쓰임은 정적 팩터리 메서드를 구현하는 경우이다.

 

 

 

 

지역 클래스

  • 네 가지 중첩 클래스 중 가장 드물게 사용
  • 지역 변수를 선언할 수 있는 곳이면 선언 가능(유효 범위도 지역 변수와 같음)
  • 멤버 클래스처럼 이름이 있고, 반복해서 사용 가능
  • 비정적 문맥에서 사용될 때만 바깥 인스턴스를 참조할 수 있으며, 정적멤버는 가질 수 없고, 가독성을 위해 짧게 작성해야함.

 

 

 

정리

  • 중첩 클래스에는 네 가지가 있으며, 각각 쓰임이 다르다.
  • 메서드 밖에서도 사용해야 하거나 메서드 안에 정의하기엔 너무 길다면 멤버클래스로 만듬
  • 멤버 클래스와 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적으로, 그렇지 않으면 정적으로 만듬
  • 중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있다면 익명 클래스로 만들고, 그렇지 않으면 지역 클래스로 만들자.
반응형

'BE > Java' 카테고리의 다른 글

[Effective Java] 아이템 26. 로 타입은 사용하지 말라  (0) 2022.10.06
[Effective Java] 아이템 25. 톱레벨 클래스는 한 파일에 하나만 담으라  (0) 2022.10.05
[Effective Java] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라  (1) 2022.09.30
[Effective Java] 아이템 22. 인터페이스는 타입을 정의하는 용도로만 사용하라  (0) 2022.09.29
[Effective Java] 아이템 21. 인터페이스는 구현하는 쪽을 생각해 설계하라  (0) 2022.09.28
  1. 아이템 24. 멤버 클래스는 되도록 static으로 만들라
  2.  
'BE/Java' 카테고리의 다른 글
  • [Effective Java] 아이템 26. 로 타입은 사용하지 말라
  • [Effective Java] 아이템 25. 톱레벨 클래스는 한 파일에 하나만 담으라
  • [Effective Java] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라
  • [Effective Java] 아이템 22. 인터페이스는 타입을 정의하는 용도로만 사용하라
멍목
멍목
개발 관련 새롭게 알게 된 지식이나 좋은 정보들을 메모하는 공간입니다.
반응형
멍목
김멍목의 개발블로그
멍목
전체
오늘
어제
  • 분류 전체보기 (514)
    • BE (190)
      • Spring (21)
      • Java (141)
      • Kotlin (6)
      • JPA (22)
    • FE (33)
      • Javascript (16)
      • Typescript (0)
      • React (5)
      • Vue.js (9)
      • JSP & JSTL (3)
    • DB (32)
      • Oracle (22)
      • MongoDB (10)
    • Algorithm (195)
    • Linux (8)
    • Git (6)
    • etc (42)
    • ---------------------------.. (0)
    • 회계 (4)
      • 전산회계 2급 (4)
    • 잡동사니 (2)

블로그 메뉴

  • 홈
  • 관리

공지사항

인기 글

태그

  • 자기개발
  • 프로젝트로 배우는 Vue.js 3
  • 더 자바 Java 8
  • MongoDB 공부
  • vue3 공부
  • 자바 테스팅 프레임워크
  • 더 자바 애플리케이션을 테스트하는 다양한 방법
  • 코테공부
  • 코틀린
  • 이펙티브 자바
  • MongoDB with Node.js
  • 알고리즘공부
  • Effective Java
  • 이펙티브자바
  • 자바 공부
  • 전산회계 2급 준비
  • MongoDB 기초부터 실무까지
  • 자바 개발자를 위한 코틀린 입문
  • 자바공부
  • java 8
  • Oracle
  • 자기 개발
  • 자기 공부
  • Java to Kotlin
  • 자기공부
  • junit5
  • 알고리즘 공부
  • JPA 공부
  • JPA
  • 코테 공부

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
멍목
[Effective Java] 아이템 24. 멤버 클래스는 되도록 static으로 만들라
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.