java inner class

2020. 9. 7. 12:05 JAVA/Java

개발 하다 보면 가끔 inner class를 사용하는 경우가 있다.

  • outer class에서만 사용하는 경우
  • outer class에만 멤버 변수로 선언되어 있고, 외부에서 생성할 수 있어야 하는 경우
  • 책임을 분리하고 싶지만, 외부로 노출하지(사용하지) 못해야 하는 경우 

나는 대략 위와 같은 기준으로 inner class를 만들어 사용한다. inner class는 non static inner class static inner class로 나뉜다. 그 외 메소드에서 선언되는 local class(지역 클래스) anonymous inner class(익명 클래스)도 있다. 이 글은 non static inner class와 static inner class만 설명한다.

non static inner class

class Outer {

    private String name;

    Outer(String name) {
        this.name = name;
    }

    void print() {
        new NonStaticInner(this.name).print();
    }

    String getName() {
        return name;
    }

    class NonStaticInner {
        private String name;

        NonStaticInner(String name) {
            this.name = name;
        }

        void print() {
            System.out.println("outer1 : " + Outer.this.name);
            System.out.println("outer2 : " + Outer.this.getName());
            System.out.println("NonStaticInner : " + this.name);
        }
    }
}

위와 같이 Outer class 내부에 선언되고, static keyword가 없는 class를 non static inner class라 한다.

  • Outer class 는 NonStaticInner class의 private 필드에 접근할 수 있다.
  • NonStaticInner class는 Outer.this를 사용할 수 있다.

테스트 코드

@Test
public void print() {
    Outer outer = new Outer("test name");
    Outer.NonStaticInner nonStaticInner = outer.new NonStaticInner(outer.getName());
    Outer.NonStaticInner nonStaticInner1 = new Outer.NonStaticInner(outer.getName()); // 컴파일 에러
    nonStaticInner.print();
}

Outer class를 생성하지 않으면, non static inner class는 생성할 수 없다. outer.new NonStaticInner();와 같이 생성한다.

non static inner class는 Outer class에 종속적이라는 의미로 볼 수 있다.

static inner class

class Outer {

    private String name;

    Outer(String name) {
        this.name = name;
    }

    void print() {
        new StaticInner(this.name).print();
    }

    String getName() {
        return name;
    }

    static class StaticInner {
        private String name;

        StaticInner(String name) {
            this.name = name;
        }

        void print() {
            System.out.println("outer" + Outer.this.name); // 컴파일 에러
            System.out.println("StaticInner : " + this.name);
        }
    }
}

위와 같이 static keyword가 붙은 class를 static inner class라 한다.

  • Outer class 는 StaticInner class의 private 필드에 접근할 수 있다.
  • StaticInner class는 Outer.this를 사용할 수 없다. (컴파일 에러)

테스트 코드

@Test
public void print() {
    Outer outer = new Outer("test name");
    Outer.StaticInner staticInner = new Outer.StaticInner(outer.getName());
    Outer.StaticInner staticInner1 = outer.new StaticInner(outer.getName()); // 컴파일 에러
    staticInner.print();
}

non static inner class와 다르게 outer.new 키워드는 사용하지 못한다. Outer class를 생성하듯, StaticInner class도 생성이 가능하다. static inner class는 Outer class에 종속적이지 않다는 의미로 볼 수 있다. 

실제 사용 예시

java collection에 java.util.LinkedList class 내부에는 Node라는 static class가 존재한다.

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

LinkedList를 이해한다면, Node class가 어떤 역할인지 감이 올 것이다. 설명은 생략한다!

출처 : https://blog.woniper.net/362?category=506090