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

yeom yaloo·2023년 11월 30일
0

Effective Java

목록 보기
12/20

4장 클래스와 인터페이스

[24. 멤버 클래스는 되도록 static으로 만들라]

  • 중첩 클래스의 4가지 종류에 대해서 알아보고 해당 종류의 클래스들이 어떨때 사용되는지 알아보자

[핵심 정리]

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

[중첩 클래스란?]

1. 의의와 코드

  • 톱레벨 클래스로 만든 클래스이다.
// 톱레벨 클래스
public class TopLevelClass{
	
    // 비정적 중첩 클래스 혹은 내부 클래스
	class InnerLevelClass{
    
    }

}
public class TopLevelClassStatic{


	// 정적 중첩 클래스
	public static class StaticInnerLevelClass{
    
    }


}

2. 정적 중첩 클래스 사용 방식과 내부 클래스 & 중첩 클래스 사용 방식 차이점

2-1. 정적 중첩 클래스 사용 방식

public static void main(String[] arg){
	StaticInnerLevelClass nestedObj = new TopLevelClassSatic.StaticInnerLevelClass();
}
  • 따로 생성자를 이용해서 객체를 생성하지 않아도 된다.
  • 이때 그저 해당 클래스에 접근하기만 하면 된다.
  • 위의 작업만 해도 정적 중첩 클래스 내부에 정의해둔 메서드에 접근할 수 있다.

2-2. 내부 클래스 & 중첩 클래스 사용 방식

public static void main(String[] arg){
	
	TopLevelClass topLevelClass = new TopLevelClass();
    
    // 비정적 중첩 클래스의 경우엔 바깥 클래스의 인스턴스 없이 생성, 접근이 불가하다!
    InnerLevelClass innerNestedClass =
    topLevelClass.new InnerLevelClass();
    
}
  • 위의 정적 중첩 클래스와 달리 탑 클래스를 객체 생성한 후에 다시 비정적 중첩 클래스를 생성해주어야 한다.
  • 위의 작업을 진행해야 해당 비정적 중첩 클래스 내부에서 정의한 메서드를 사용할 수 있다.

3. 중첩 클래스의 종류

  • 중첩 클래스는 말 그대로 바깥 클래스 안에 다시 클래스를 정의한 것을 의미한다.
  • 이때 static을 달았으면 static nested class고 나머지는 inner class에 해당한다.
  • 이때 inner class의 경우엔 또 다시 안에서 사용되는 방법에 따라서 종류가 세가지로 나뉜다.

3-1. 정적 멤버 클래스

  • 클래스 안에 선언되고 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 동일하다.
    -private로 정적 중첩 클래스를 선언하면 바깥 클래스에서만 접근할 수 있다.
  • 주로 바깥 클래스와 함께 사용할 때 유용한 public 도우미 클래스로 쓰인다.

3-2. 비정적 멤버 클래스

  • static이 붙지 않은 중첩 클래스로 의미상의 차이는 정적 멤버 클래스와 크게 다르다.
  • 해당 비정적 멤버 클래스의 경우엔 바깥 클래스의 인스턴스와 암묵적으로 연결되어 있다.
  • 바깥 인스턴스의 메서드를 호출하거나 바깥 인스턴스의 참조를 가져올 수 있다.
  • 비정적 멤버 클래스의 경우엔 바깥 클래스의 인스턴스 없이는 생성할 수 없다.
  • inner class가 이에 해당한다. (해당 작업이 바깥 인스턴스와 연결되어 있고, 바깥 인스턴스 참조 없이는 해당 중첩 클래스 생성도 클래스 내의 메서드 접근도 불가하기 때문이다.)
  • 보통은 생성자 없이도 만들어지지만 바깥_인스턴스.new non-static_nested_class(args)으로 수동 생성하기도 한다.
  • 해당 클래스는 바깥 클래스 내부에 생성되어 메모리를 차지하고 생성 시간도 더 걸린다.
  • 바깥 인스턴스에서 접근할 일이 있을 때만 사용되는 비정적 내부 클래스이기 때문에 바깥에서 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.

3-3. 익명 클래스

  • 이름이 없는 클래스가 익명 클래스이다.
  • 해당 클래스는 바깥 클래스의 멤버가 아니다. 이는 멤버와 달리 쓰는 시점에 선언과 동시에 인스턴스가 만들어지기 때문이다.
    • 멤버라면 인스턴스가 만들어지는 시점은 해당 인스턴스를 생성하는 시점이기 때문이다. (말이 이상하지만 대부분의 클래스 내부의 멤버들은 클래스에서 객체 생성 시점이기 때문에 사용시점인 익명 클래스와는 생성 시점이 다르다)

3-4. 지역 클래스

  • 가장 드물게 사용한다.
  • 지역 클래스느 지역변수를 선언할 수 있는 곳이라면 어디든 선언 가능하다.
  • 지역 변수처럼 사용한다.

[static 중첩 클래스를 사용하자]

  • 정적 중첩 클래스를 사용해야 하는 경우?
    : 메서드 밖에서도 사용해야하고 메서드 안에서 정의하기에 너무 긴 경우라면 멤버 클래스로 만들자
  • 비정적 중첩 클래스를 사용해야 하는 경우?
    : 인스턴스 각각이 바깥 인스턴스를 참조하는 경우엔 비정적 중첩 클래스를 사용하자
  • 익명 클래스를 사용해야 하는 경우?
    : 중첩 클래스가 한 메서드 안에서 사용되고 그 인스턴스를 생성하는 지점이 한곳이면서 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있는 경우라면 익명 클래스를 사용하자
  • 그렇지 않으면 지역 클래스로 만들어 사용하자
profile
즐겁고 괴로운 개발😎

0개의 댓글