ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 내부(inner) 클래스와 내부(inner) static 클래스의 차이
    Language/Java 2020. 8. 25. 16:58
    728x90
    반응형

    이번 글에서는 클래스 안에 클래스가 존재하는 경우에 대해서 정리해보려 한다. 

    public class Test {
        
        class InnerClass {
            // InnerClass
        }
        
        static class InnerStaticClass {
            // static InnerClass
        }
    }

    내부 클래스(Inner Class)란 위와 같이 클래스 안에 클래스가 존재하는 형태이다. 그러면 내부 클래스에서 static이 붙은 것과 붙지 않은 것의 차이점은 어떤 것일까? 라고 생각했을 때 나는 static이 붙었기 때문에 static 변수, static 메소드처럼 공유해서 사용하는 클래스인가? 라고 생각을 하였다. 하지만 나의 생각은 누구나 한번 쯤 할만한 잘못된 생각이었다. 이유가 무엇인지 알아보자.

     

     

    1. 내부 클래스

    public class Test {
    
        class InnerClass {
            // InnerClass
        }
    
        static class InnerStaticClass {
            // static InnerClass
        }
    
        public static void main(String[] args) {
            Test.InnerClass innerClass1 = new Test().new InnerClass();
            Test.InnerClass innerClass2 = new Test().new InnerClass();
    
            if (innerClass1 == innerClass2) {
                System.out.println("내부 클래스는 같은 참조");
            } else {
                System.out.println("내부 클래스는 다른 참조");
            }
        }
    }

    먼저 InnerClass 클래스의 객체를 만들기 위해서는 Test 클래스의 객체를 먼저 만들어야 한다. 따라서 new 연산자를 두번 사용하여 외부 클래스에 대한 인스턴스를 이용해서 내부 클래스의 인스턴스를 생성한다. 위의 코드의 결과는 당연하다 할 수 있지만 클래스 이기 때문에 다른 인스턴스를 만들어서 다른 참조의 결과를 갖는다.

     

     

    2. 내부 static 클래스

    public class Test {
    
        class InnerClass {
            // InnerClass
        }
    
        static class InnerStaticClass {
            // static InnerClass
        }
    
        public static void main(String[] args) {
            Test.InnerStaticClass innerClass1 = new Test.InnerStaticClass();
            Test.InnerStaticClass innerClass2 = new Test.InnerStaticClass();
    
            if (innerClass1 == innerClass2) {
                System.out.println("내부 클래스는 같은 참조");
            } else {
                System.out.println("내부 클래스는 다른 참조");
            }
        }
    }

    이번에는 내부 staic 클래스의 객체 2개를 만들어 보자. 두개의 인스턴스는 같을까 다를까? 왠지 나의 생각을 결과가 같다고 예상하였다. 하지만 결과는 두개 인스턴스의 참조값은 다르다. 다만 static 이기 때문에 외부클래스(Test)의 객체를 만들지 않고 InnerStaticClass를 사용할 수 있다는 점이 차이가 있다. 

     

     

    내부 클래스를 사용하는 이유

    • 외부 클래스와 내부 클래스가 긴밀한 관계를 맺을 때 사용한다.
    • 내부 클래스에서 외부 클래스의 멤버에 쉽게 접근할 수 있다.
    • 서로 관련있는 코드를 묶어서 코드의 캡슐화를 증가시킨다.
    • 외부에서는 내부 클래스에 접근할 수 없기 때문에 코드의 복잡성을 줄일 수 있다.

     

     

    내부 클래스와 static 내부 클래스의 차이

    public class Test {
        
        void myTest() {
            
        }
    
        class InnerClass {
            void innerClassMethod() {
                Test.this.myTest();
            }
        }
    
        static class InnerStaticClass {
            Test.this.myTest();    // 에러
        }
    }

    위에서 말했던 것처럼 내부 클래스는 Test 클래스의 객체를 만들어야 사용할 수 있고, static 내부 클래스는 Test 객체가 존재하지 않아도 사용할 수 있다는 차이가 있었다. 따라서 위의 코드를 보면 static 내부 클래스에서 Test 클래스의 메소드에 접근하면 컴파일 에러가 발생한다. 이유를 생각해보면 당연하다. Test 객체를 만들기 전에 InnerStaticClass를 사용할 수 있기 때문에 참조할 수 없는 것이다.

     

     

    하지만 이러한 단점이 존재해도 static을 사용하지 않는 것의 단점이 더 크기 때문에 내부 클래스는 가능한 static으로 만들어야한다.

     

     

    static이 붙지 않았을 때 단점

    • 참조값을 담아야 하기 때문에, 인스턴스 생성시 시간적, 공간적으로 성능이 낮아진다
    • 외부 인스턴스에 대한 참조가 존재하기 때문에, 가비지 컬렉션이 인스턴스 수거를 하지 못하여 메모리 누수가 생길 수 있다.

     

     

    만약 static키워드를 사용하고 싶지 않다면 내부 클래스 보다는 별개의 클래스로 만드는 것이 좋습니다.

     

     

     

    Reference

    https://siyoon210.tistory.com/141

     

     

     

    반응형

    댓글

Designed by Tistory.