본문 바로가기

Java

[Java] 인스턴스 내부 클래스

728x90

인스턴스 내부 클래스(Instance Inner Class)란?

인스턴스 내부 클래스는 외부 클래스의 인스턴스에 속하는 클래스를 의미합니다. 즉, 인스턴스 내부 클래스는 외부 클래스의 객체를 생성해야만 사용할 수 있는 클래스입니다.

예시 코드

class Outer {
    // 인스턴스 변수
    private final int number = 10;

    // 인스턴스 내부 클래스
    class Inner {
        void display() {
            // 외부 클래스의 인스턴스 변수에 접근
            System.out.println("Outer class number: " + number);
        }
    }

    // 인스턴스 메소드
    void createInner() {
        Inner inner = new Inner();  // 내부 클래스는 외부 클래스 객체에서만 생성 가능
        inner.display();
    }
}

 

인스턴스 내부 클래스 특징

1. 외부 클래스의 멤버에 접근할 수 있습니다.

일반적으로 클래스의 인스턴스 변수에 private으로 설정하면 다른 클래스에서는 접근할 수 없습니다. 그러나 인스턴스 내부 클래스는 private으로 접근을 제한하더라도 해당 인스턴스 변수에 접근할 수 있습니다.

class GeneralClass {
    private final String message = "hello world";
}

class Test {
    public static void main(String[] args) {
        GeneralClass generalClass = new GeneralClass();
        // 아래 코드는 접근 불가능
        // System.out.println(generalClass.message); 
    }
}

 

또한 인스턴스 내부 클래스는 외부 클래스의 private 맴버에도 접근할 수 있습니다.

class Outer {
    private final int number = 10;

    // 인스턴스 내부 클래스
    class Inner {
        void display() {
            // 외부 클래스의 인스턴스 변수에 접근
            System.out.println("Outer class number: " + number);
        }
    }

    void createInner() {
        Inner inner = new Inner();  // 내부 클래스는 외부 클래스 객체에서만 생성 가능
        inner.display();
    }
}

 

 

2. 외부 클래스에 대한 의존성이 있습니다.

인스턴스 내부 클래스는 외부 클래스의 객체 없이는 사용할 수 없습니다. 외부 클래스의 인스턴스를 생성한 후에야 내부 클래스를 사용할 수 있습니다.

class Outer {
    private final int number = 10;

    // 인스턴스 내부 클래스
    class Inner {
        void display() {
            // 외부 클래스의 인스턴스 변수에 접근
            System.out.println("Outer class number: " + number);
        }
    }

    void createInner() {
        Inner inner = new Inner();  // 내부 클래스는 외부 클래스 객체에서만 생성 가능
        inner.display();
    }
}

class Test {
    public static void main(String[] args) {
        Outer outer1 = new Outer();
        outer1.createInner();

        // 외부 클래스 객체에서만 접근 가능
        Outer outer2 = new Outer();
        Outer.Inner inner = outer2.new Inner();  // 외부 클래스 객체를 통해 접근
        inner.display();
    }
}

또한, 접근 제어자를 통해 내부 클래스의 접근을 제한할 수 있습니다.

 

class Outer {
    private final int number = 10;

    // 인스턴스 내부 클래스 (private 접근 제어자)
    private class Inner {
        void display() {
            // 외부 클래스의 인스턴스 변수에 접근
            System.out.println("Outer class number: " + number);
        }
    }

    void createInner() {
        Inner inner = new Inner();  // 내부 클래스는 외부 클래스 객체에서만 생성 가능
        inner.display();
    }
}

class Test {
    public static void main(String[] args) {
        Outer outer1 = new Outer();
        outer1.createInner();

        // 컴파일 오류: Inner는 외부에서 접근 불가능
        // Outer outer2 = new Outer();
        // Outer.Inner inner = outer2.new Inner();  // 오류 발생
        // inner.display();
    }
}

 

 

언제 사용해야 할까요?

1. 긴밀하게 연관되어 있을 때

인스턴스 내부 클래스는 외부 클래스의 인스턴스 변수와 메소드에 접근할 수 있기 때문에, 두 클래스가 긴밀하게 연관되어 있을 때 사용합니다. 예를 들어, 게임 캐릭터와 그 캐릭터만 사용할 수 있는 아이템처럼 강한 관계가 있을 때 유용합니다.

 

2. 캡슐화와 내부 구현을 숨기고 싶을 때

내부 클래스는 private 접근 제어자를 통해 외부에서 직접 접근을 차단할 수 있습니다. 이렇게 하면 외부 클래스의 내부 구현을 숨기고, 외부 클래스의 메서드를 통해서만 접근할 수 있도록 할 수 있습니다.

언제 사용하면 안될 까요?

1. 연관성이 적을 때: 두 클래스 간에 관계가 약한 경우 인스턴스 내부 클래스를 사용할 필요가 없습니다. 클래스를 독립적으로 설계하고, 객체 간의 의존성을 최소화하는 것이 좋습니다.

 

2. 복잡한 구조를 만들 때: 내부 클래스에 너무 많은 책임을 주면 코드가 복잡해지고 유지보수가 어려워질 수 있습니다.

 

3. 성능상의 이유: 인스턴스 내부 클래스는 외부 클래스 객체에 대한 참조를 유지하고 있기 때문에, 가비지 컬렉션에서 외부 클래스 객체가 제거되지 않는 상황이 발생할 수 있습니다. 이로 인해 메모리 누수 등의 문제가 발생할 수 있습니다.

따라서, 내부 클래스가 필요한 경우가 아니라면 외부 클래스로 독립시켜 사용하는 것이 더 효율적입니다.

 

 

 

요약

  • 인스턴스 내부 클래스는 외부 클래스의 인스턴스와 연결되어 있으며, 외부 클래스의 private 멤버에도 접근할 수 있습니다.
  • 외부 클래스 객체에서만 생성할 수 있기 때문에 외부 클래스에 의존적입니다.
  • 두 클래스가 강하게 연관되어 있거나, 캡슐화를 원하는 경우에 사용해야 하며, 성능이나 복잡성에 문제가 될 경우 사용을 피하는 것이 좋습니다.
728x90

'Java' 카테고리의 다른 글

[Java] 동등성 (equals(), hashCode())  (0) 2025.01.05
[Java] String, StringBuffer, StringBuilder 차이점  (1) 2025.01.03
[Java] for-each 루프  (0) 2024.12.04
[Java] 리스트 인터페이스 구현  (3) 2024.11.26
[Java] 1급 커넥션  (0) 2024.10.14