Link
Today
Total
10-17 00:15
Archives
관리 메뉴

초보개발자 긍.응.성

(이펙티브 자바 3) 24. - 멤버 클래스는 되도록 static으로 만들라 본문

책 정리/이펙티브 자바 3

(이펙티브 자바 3) 24. - 멤버 클래스는 되도록 static으로 만들라

긍.응.성 2020. 10. 28. 01:06
반응형

중첩 클래스의 종류와 각각의 중첩 클래스를 언제 그리고 왜 사용해야 하는지 알아보자.

중첩 클래스 (nested class)

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

정적 멤버 클래스

정적 멤버 클래스는 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 동일하다. 정적 멤버 클래스는 다른 정적 멤버와 똑같은 접근 규칙을 적용받는다. 정적 멤버 클래스는 흔히 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스로 쓰인다.

public class Calculator {

    public int calculate(int num1, int num2, Operation operation) {
        switch (opertaion) {
            case Operation.PLUS:
                // plus
                break;
            case Operation.MINUS:
                // minus
                break;
            case Operation.MULT:
                // mult
                break;
            case Operation.DIVIDE:
                // divide
                break;
        }
    }

    public static enum Operation {
        PLUS, MINUS, MULT, DIVIDE
    }

}

public static void main(String[] args) {
    int num1 = 5;
    int num2 = 55;
    Calculator.Operation operation = Calculator.Operation.PLUS; // 바깥클래스가 생성되지 않아도 접근 가능
    Calculator.calculate(num1, num2, operation);
}

비정적 멤버 클래스

정적 멤버 클래스와 차이는 구문상 static이 붙어있고 없고 이지만, 의미상으로 차이가 꽤 크다. 비정적 멤버 클래스의 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결된다. 비정적 멤버 클래스의 인스턴스 메서드에서 정규화된 this를 사용해 바깥 인스턴스의 메서드를 호출하거나 바깥 인스턴스의 참조를 가져올 수 있다. 비정적 멤버 클래스의 인스턴스와 바깥 인스턴스 사이와의 관계는 멤버 클래스가 인스턴스화 될 때 확립되며, 더 이상 변경할 수 없다.

멤버 클래스는 다음과 같이 인스턴스화 할 수 있다.

  1. 바깥 클래스의 인스턴스 메서드에서 비정적 멤버 클래스의 생성자를 호출
  2. OuterClass.new InnerMemberClass(args) 를 호출하여 수동으로 생성

비정적 멤버 클래스는 어댑터를 정의할 때 자주 쓰인다.

비정적 멤버 클래스의 단점

비정적 멤버 클래스의 단점은 바깥 클래스에 대한 숨은 외부 참조로 인해 발생한다.

  • 바깥 인스턴스 숨은 외부 참조가 비정적 멤버 클래스의 인스턴스 안에 만들어져 메모리 공간을 차지하며, 생성 시간도 더 걸린다.
  • 바깥 클래스의 인스턴스에 대한 참조가 해제되어도 비정적 멤버 클래스는 숨은 외부 참조를 갖고있기에 가비지 컬렉션이 바깥 클래스의 인스턴스를 수거하지 못하여 메모리 누수가 생길 수 있다.

 

private 정적 멤버 클래스

바깥 클래스가 표현하는 객체의 한 부분(구성요소)을 나타낼 때 쓴다. 바깔 클래스 내부에서만 참조가 가능하다.

익명 클래스

익명 클래스는 바깥 클래스의 멤버가 아니다. 쓰이는 시점에 선언과 동시에 인스턴스가 만들어진다. 비정적인 문맥에서 사용될 때만 바깥 클래스의 인스턴스를 참조할 수 있다. 정적 문맥에서는 상수 변수 이외의 정적 멤버는 가질 수 없다.

지역 클래스

가장 많이 사용되지 않는 중첩 클래스 형식이다. 지역 클래스는 지역 변수를 선언할 수 있는 곳이면 어디서든 선언할 수 있고, 유효 범위도 지역변수와 같다. 정적과 비정적 문맥에 대한 참조 방식은 익명 클래스와 같으며, 이름을 갖기에 반복해서 사용할 수 있다는 것이 차이점이다.

정리

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

반응형
Comments