JVM

자바 내부 클래스(Inner Classes)

kyoulho 2024. 3. 1. 11:59

자바에서 내부 클래스는 다른 클래스 내에 정의된 클래스를 말한다. 내부 클래스는 특정 클래스에 종속되어 있으며, 외부 클래스의 멤버에 접근할 수 있다. 내부 클래스는 코드의 구조화, 은닉성, 캡슐화를 강화하는 데 사용될 수 있다.

 

장점

내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.

사용이 제한된 클래스를 내부에 둠으로써 코드의 복잡성을 줄일 수 있다.

 

종류


인스턴스 클래스(Instance Class)

외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 인스턴스멤버처럼 다루어진다. 주로 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언된다.

public class OuterClass {
    private int outerField;

    public class InnerClass {
        public void innerMethod() {
            // outerField에 접근 가능
            System.out.println("Inner Method: " + outerField);
        }
    }
}

 

정적 내부 클래스 (Static Inner Class)

외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 정적 멤버처럼 다루어진다. 주로 외부 클래스의 static멤버, 특히 static 메서드에서 사용될 목적으로 선언된다.

public class OuterClass {
    private static int staticOuterField;

    public static class StaticInnerClass {
        public void staticInnerMethod() {
            // staticOuterField에 접근 가능
            System.out.println("Static Inner Method: " + staticOuterField);
        }
    }
}

 

지역 내부 클래스 (Local Inner Class)

메소드 내에서 선언되고 메소드 내에서만 사용 가능한 클래스이다. 주로 한정적인 범위에서만 사용되어야 하는 경우에 활용된다.

public class OuterClass {
    public void someMethod() {
        class LocalInnerClass {
            public void localInnerMethod() {
                System.out.println("Local Inner Method");
            }
        }

        LocalInnerClass localInner = new LocalInnerClass();
        localInner.localInnerMethod();
    }
}

 

익명 내부 클래스 (Anonymous Inner Class)

클래스의 선언과 객체의 생성을 동시에 하는 클래스이다. 주로 인터페이스나 추상 클래스의 객체를 생성할 때 사용된다.

public class OuterClass {
    public void someMethod() {
        Runnable anonymousInner = new Runnable() {
            @Override
            public void run() {
                System.out.println("Anonymous Inner Class");
            }
        };

        Thread thread = new Thread(anonymousInner);
        thread.start();
    }
}

 

내부 클래스에 대한 조언 (Effective Java)


 

"Effective Java"에서는 정적 내부 클래스를 사용하는 것이 좋다는 조언이 있다. 또한 IDE에서 내부 클래스를 static으로 만들라고 하기도 한다. 이것은 여러 가지 이유로 인해 더 나은 설계와 성능을 제공할 수 있기 때문으로 몇 가지 주요한 이유는 다음과 같다.

  • 독립성: 정적 내부 클래스는 외부 클래스의 인스턴스에 종속되지 않기 때문에 독립적으로 사용할 수 있다. 이는 내부 클래스가 외부 클래스의 인스턴스에 의존하지 않고도 인스턴스화될 수 있음을 의미한다.
  • 가독성: 정적 내부 클래스는 외부 클래스와 독립적으로 사용되기 때문에 코드가 더 간결하고 가독성이 향상될 수 있다. 또한, 외부 클래스의 이름을 사용하여 참조하기 때문에 코드를 읽고 이해하기가 더 쉬울 수 있다.
  • 네스팅(Nesting)의 편리성: 정적 내부 클래스는 외부 클래스의 네스팅에 편리함을 제공하며, 다른 클래스에서도 사용될 때 더 깔끔한 코드 구조를 유지할 수 있다.
  • 메모리 효율성: 정적 내부 클래스는 외부 클래스의 인스턴스를 참조하지 않기 때문에 메모리 사용이 효율적이다. 일반적인 내부 클래스는 외부 클래스의 인스턴스에 대한 참조를 가지고 있는데, 이는 객체가 생성될 때마다 불필요한 참조를 가지게 된다.

"Effective Java"에서는 또한 내부 클래스의 종류에 따라 사용하는 상황이 달라진다는 것을 강조하고 있다. 따라서 어떤 종류의 내부 클래스를 사용할지는 상황과 요구사항에 따라 결정되어야 한다.

정리하자면 외부 참조가 유지된다는 것은 메모리에 대한 참조가 유지되고 있다는 뜻으로 GC가 메모리를 회수할 수 없다. 당연히 이는 메모리 누수를 부르기도 한다. 항상 외부 인스턴스의 참조를 통해야 하므로 성능 상 비효율적이다. 결국 외부 인스턴스에 대한 참조가 필요하지 않다면 static nested class로 만드는 것이 낫다.

 

 

 

728x90

'JVM' 카테고리의 다른 글

StringBuffer vs StringBuilder  (0) 2024.07.22
java.security.invalidKeyException: Illegal Key Size  (0) 2024.05.04
쓰레드 동기화  (0) 2024.03.01
Google JIB  (0) 2024.01.30
JVM  (0) 2023.12.19