Java Nested - 내부 클래스
이전 정적 중첩 클래스와 바깥클래스와의 관계가 없었다.
이번 내부 클래스에서는 바깥클래스의 인스턴스 요소가 되어 소속된다.
정적 중첩 클래스
- static 키워드로 생성
- 바깥클래스의 인스턴스로 소속되지 않음
내부 클래스
- static 키워드 없이 생성
- 바깥 클래스의 인스턴스로 소속
예제코드
public class InnerOuter {
private static int outClassValue = 3;
private int outInstanceValue = 2;
class Inner {
private int innerInstanceValue = 1;
public void print() {
// 자기 자신 접근
System.out.println(innerInstanceValue);
// 외부 클래스의 인스턴스 멤버로 접근 가능, private 또한 접근 가능
System.out.println(outInstanceValue);
// 외부 클래스의 클래스 멤버로 접근 가능, private 또한 접근 가능
// 정적 변수
System.out.println(outClassValue);
}
}
}
- 내부 클래스는 static 없음
- 내부 클래스
- 자신의 멤버는 접근 가능
- 바깥클래스의 인스턴스 멤버 접근 가능
- 바깥클래스의 클래스 멤버 접근 가능
private 접근제어자
- private 접근제어자는 같은 클래스 안에서만 접근 가능
- 내부 클래스 또한 바깥 클래스 안에 있다. 즉, 내부 클래스는 바깥클래스의 private 접근제어자를 자유롭게 접근 가능하다.
내부 클래스 인스턴스 생성
외부에서 InnerOuter 내부클래스를 호출하는 예제코드를 바라보자.
Main.class
public class Main {
public static void main(String[] args) throws Exception {
InnerOuter outer = new InnerOuter();
InnerOuter.Inner inner = outer.new Inner();
}
}
내부 클래스 인스턴스 생성 문법이 특이한 것을 볼 수 있다.
먼저, 바깥클래스의 인스턴스 참조가 필요함으로 먼저 생성한다. (new InnerOuter()
)
인스턴스 내부 참조점(.)을 통해 새로운 내부 클래스 소속과 인스턴스를 새로 생성하였다.(outer.new Inner()
)
코드의 Inner()는 InnerOuter()의 인스턴스 참조를 갖고 있다.
이 생성의 핵심은 인스턴스의 인스턴스 생성으로 이루어진 점이다.
inner.print();
System.out.println(inner.getClass());
1
2
3
class InnerOuter$Inner
중첩,내부 클래스는 $달러로 표시된다.
생성이 안되는 케이스
다음과 같이 선언하여 사용할 수 없다.
내부 클래스 생성에는 바깥클래스의 인스턴스가 반드시 필요하다.
new InnerOuter().Inner();
java: cannot find symbol
// InnerOuter outer = new InnerOuter();
InnerOuter.Inner inner = outer.new Inner();
java: cannot find symbol
참고
내부 클래스 생성에는 바깥 클래스 인스턴스 안에 생성한다고 하였으나 개념으로만 그렇다.
실제에는 바깥 클래스와 내부 클래스 각각 독립적으로 생성한 모습이고 내부 클래스는 바깥클래스의 참조 보관하는 그림이다.