Skip to content

Latest commit

 

History

History
152 lines (118 loc) · 4.59 KB

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

File metadata and controls

152 lines (118 loc) · 4.59 KB

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

중첩 클래스란?

중첩 클래스란 다른 클래스 내부에 정의된 클래스를 말한다.

  • 두 클래스의 멤버들을 쉽게 접근 가능
  • 외부로부터 불필요한 관계 클래스를 감춤으로써 코드의 복잡성 감소

중첩 클래스의 종류

  • static으로 선언한 멤버 클래스를 static 중첩 클래스라고 부른다.
    • 정적 멤버 클래스
  • non-static 멤버 클래스를 내부 클래스라고 부른다.
    • 비정적 멤버 클래스
    • 익명 클래스
    • 지역 클래스

정적 멤버 클래스

정적 멤버 클래스는 바깥 클래스 내부에 static으로 선언된 클래스이다.

  • 바깥 클래스의 private 멤버에도 접근 가능
  • 흔히 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스로 쓰인다.
public class Person {
    
    private final String name;
    private final int age;
    private final int weight;
    private final int height;
    
    public static class Builder {
        private final String name;
        private final int age;
        
        private int weight = 0;
        private int height = 0;
        
        public Builder(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        public Builder weight(int val) {weight = val; return this;}
        
        public Builder height(int val) {height = val; return this;}
        
        public Person build() {
            return new Person(this);
        }
    }
    
    private Person(Builder builder) {
        name = builder.name;
        age = builder.age;
        weight = builder.weight;
        height = builder.height;
    }
}
Person JJANG9 = new Person.Builder("짱구", 7)
    .weight(80).height(200).build();

비정적 멤버 클래스

비정적 멤버 클래스란 바깥 클래스 내부에 static 키워드 없이 선언된 클래스이다.

  • 바깥 인스턴스 없이는 존재할 수 없다.
  • 인스턴스 메서드에서 정규화된 this를 사용해 바깥 인스턴스의 메서드를 호출한다거나 바깥 인스턴스를 참조할 수 있다.
public class Outer {
    String name = "짱구";

    public void run() {
        Inner inner = new Inner();
        inner.run();
    }

    public class Inner {
        public void run() {
            System.out.println(Outer.this.name);
        }
    }
}

결론

멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.

  • static을 생략하면 바깥 인스턴스로의 숨은 외부 참조를 갖게 되고 심각한 경우 GC가 바깥 인스턴스를 수거하지 못하는 경우가 발생한다. (메모리 누수)

익명 클래스

익명 클래스는 사용 시점에 인스턴스화 되어 한번만 사용할 수 있게 만든 클래스이다.
익명이라 이름이 없기 때문에 생성자를 가질 수 없고 단 하나의 클래스를 상속받거나 하나의 인터페이스만 구현 가능하다.

  • 익명 클래스에 새롭게 정의된 필드와 메서드는 익명 클래스 내부에서만 사용 가능하다.
  • 람다가 나오면서 익명 클래스는 빠이~
public class Anonymous {
    public void show() {
    }
}

public class Main {
    public static void main(String[] args) {
        Anonymous anonymous = new Anonymous() {
            public void hide() {
                System.out.println("는 못말려!");
            }

            @Override
            public void show() {
                System.out.print("짱구");
                hide();
            }
        };
        
        //anonymous.hide(); 호출 불가
        anonymous.show();
    }
}

지역 클래스

지역 클래스는 가장 드물게 사용되는 중첩 클래스이다.

  • 접근 제한자(public, private) 및 static을 붙일 수 없다.
    • 메서드 내부에서만 사용되기 때문에 접근을 제한할 필요가 없다.
  • 정적 멤버(정적 필드와 메서드)를 가질 수 없다.
public class OuterJJANG9 {
    private String outerMessage = "짱";
    
    public void method() {
        class LocalJJANG9 {
            public void print() {
                String localMessage = "구";
                System.out.println(outerMessage + localMessage);
            }
        }
        
        LocalJJANG9 localJJANG9 = new LocalJJANG9();
        localJJANG9.print();
    }
}