본문 바로가기
java/기타

[java] 내부 클래스(static vs non-static)

by 권성호 2022. 6. 18.

사실이 아니라 공부한 내용과 생각을 정리한 글입니다. 언제든 가르침을 주신다면 감사하겠습니다.

 

특정 클래스 속에 있는 클래스를 내부 클래스라고 부른다.

내부 클래스는 static으로 만들 수도 있고 non-static으로 만들 수도 있는데 이 차이에 대해 정확하게 알고 싶어서 공부하게 되었다.

 

다음과 같은 code 가 있다고 하자.

package extra.static_code;

public class OuterClassFactory {
    class InnerClass {
        private String val;
        InnerClass(String val){
            this.val = val;
        }
    }
    static class StaticInnerClass {
        private String val;
        StaticInnerClass(String val){
            this.val = val;
        }
    }

    public InnerClass createInnerClass(){
        return new InnerClass("InnerClass");
    }

    public StaticInnerClass createStaticInnerClass(){
        return new StaticInnerClass("StaticInnerClass");
    }
}

OuterClassFactory 클래스가 외부에 있고 내부 클래스로 InnerClass와 StaticInnerClass 가 존재한다.

또한 OuterClassFactory 클래스에는 각각의 내부 클래스의 인스턴스를 생성하는 메서드가 있다.

이 클래스들을 대상으로 하는 아래 테스트 코드를 작성했다.

package extra.static_code;

public class Test {
    public static void main(String[] args) {
        //outerClass 의 인스턴스를 통해 inner class 인스턴스 생성
        OuterClassFactory factory = new OuterClassFactory();
        OuterClassFactory.InnerClass innerClass1 = factory.createInnerClass();
        OuterClassFactory.StaticInnerClass staticInnerClass1 = factory.createStaticInnerClass();

//        //outerClass 의 인스턴스를 없이 inner class 인스턴스 생성
//        OuterClassFactory.InnerClass innerClass2 = new OuterClassFactory.InnerClass("InnerClass");
        OuterClassFactory.StaticInnerClass staticInnerClass = new OuterClassFactory.StaticInnerClass("StaticInnerClass");
    }
}

우선 OuterClassFactory 클래스의 인스턴스를 만들고 그 인스턴스의 메소드를 통해서 내부 클래스를 생성할 경우, InnerClass와 StaticInnerClass 모두 문제없이 생성되는 것을 확인할 수 있다.

 

하지만 OuterClassFactory 와 독립적으로 내부 클래스를 생성할 경우 StaticInnerClass는 잘 생성되는 반면, InnerClass는 컴파일 오류를 경험하게 된다.

InnerClass 의 독자적인 생성은 컴파일 타임에 걸러진다..

여기서 한가지 알 수 있는 사실은, Static 내부 클래스의 경우 독자적인 인스턴스를 만들 수 있지만, Non-Static 내부 클래스의 경우는 불가능하다는 것이다.

즉, Non-Static 내부 클래스는 반드시 외부 클래스의 인스턴스를 통해 생성돼야 한다.

 

또 하나의 특징을 살펴보기 위해 Test Code를 디버깅해보자.

Test code 디버깅

특이한 점을 발견할 수 있는데, Non-Static innerClass의 경우 자신의 외부 클래스의 인스턴스를 참조로 가지고 있다는 것이다.

 

결론적으로 Non-Static innerClass의 경우 아래 두 가지 특징을 가진다.

  1. 독자적인 인스턴스 화가 불가능 하고 반드시 외부 클래스의 인스턴스를 통해서만 인스턴스 화가 가능하다.
  2. 인스턴스화 되었을 경우 자동으로 자신을 생성한 외부 클래스의 인스턴스를 참조로 갖는다.

 

그렇다면, Static과 Non-Static 은 언제 어떻게 사용되어야 할까?

Non-Static 으로 만들 경우 외부 클래스와의 결합도가 높아진다. 

이는 어떤 상황에서는 캡슐화가 잘 된다는 의미가 될 수 있고, 다른 어떤 상황에서는 강한 의존성이 발생한다는 의미가 될 수 있다. 따라서...

개념적으로, 내부 클래스의 인스턴스가 외부 클래스의 인스턴스 없이 독립적으로 존재할 수 없다면(개념적으로 강하게 결합되어 있다면) Non-Static으로 만드는 것이 좋아 보인다.

반대로, 내부 클래스의 인스턴스가 외부 클래스의 인스턴스와 독립적으로 존재할 수 있다면(개념적으로 분리되어 있다면) Static 으로 만드는 것이 좋아 보인다.

 

개념적으로 분리되어 있다면 Static 내부 클래스보다 별도의 클래스를 만들고 합성을 통해 사용하도록 하는 것이 더 깔끔할 것 같기도 하다.(이 부분은 좀 더 고민해볼 필요가 있을 것 같다.)

 

참고자료

 

 

 

 

 

 

 

댓글