JAVA/자바의 신

16장. 클래스 안에 클래스가 들어갈 수도 있구나

hyunsb 2024. 1. 7. 21:11
💡 해당 글은 『자바의 신 3판』을 복습하며 도서의 내용과 본인의 주관적인 생각을 정리한 글입니다.

☁️ 내용정리

Nested class

자바에서 클래스 안에 클래스가 들어갈 수도 있다. 이를 Nested class라 말한다.

클래스 안에 클래스를 선언하는 이유는 특정 클래스가 해당 클래스에서만 쓰이는 경우, 내부에서 간단하게 구현되어 사용되는 경우, 특정 클래스에 종속되는 개념인 경우 등이 있는데, top-level class로 선언되어서 얻는 이점이 없기 때문에 nested class로 선언한다.

  • 한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리할 필요가 있는 경우
  • 특정 클래스의 private 자원을 특정 클래스에서 접근하고 싶은 경우 (캡슐화를 위해)
  • 가독성을 위해

Nested class는 크게 두 가지로 분류 된다.

  • Static nested class
  • inner class (익명클래스, local inner class )

 

static nested class

public class Nested {

    private static void method() { } 

    private void instanceMethod() { }

    private static class StaticPrivateNested {
        static int a = 1;

        public void callMethod() {
            Nested.method();
        }
    }

    public static class StaticPublicNested {
        static int a = 1;

        public void callMethod() {
            Nested.method();
        }
    }
}
new Nasted.StaticPublicNested();

클래스 밖에서 static처럼 접근하여 객체를 생성할 수 있음.

 

inner class

public class Nested {

    public class InnerClass {

    }
}
class Main {
    public static void main(String[] args) throws Exception {
    // Nested.InnerClass innerClass = new Nested.InnerClass();

    Nested nested = new Nested();
    Nested.InnerClass innerClass = nested.new InnerClass();
    }
}

외부 클래스의 인스턴스를 통해서만 생성 가능.

 


 

☁️ 내 생각

static nested class는 보통 외부 클래스의 네임스페이스를 정리하기 위해 사용되는 것 같다. 왜냐하면 외부 클래스의 인스턴스 없이 독자적으로 인스턴스를 생성할 수 있기 때문이다.

나는 Spring기반 웹 서버를 만들 때, Request, Response DTO를 생성하는 과정에서 자주 사용했다.

public class UserResponse {

    public static class InfoDTO {
        public final String username;
        public final int userAge;
        // ...
    }

    public static class ContactDTO {
        public final String phoneNumber; // 보통 외부로 전달하지 않는다.
        public final String email;
    }
}

 

inner class는 외부 인스턴스의 모든 자원과 바인딩되는 강한 의존성을 가지고 있다. 독자적인 인스턴스 생성은 불가능하고, 외부 인스턴스를 통해서만 생성할 수 있으며, 외부 인스턴스의 모든 자원을 사용할 수 있다.

장점은 외부 클래스의 private 인스턴스 지원에 접근할 수 있다는 것이다. 이는 외부 클래스와 강하게 결합하며, 캡슐화를 더 용이하게 할 수 있다고 생각은 드나, 아직까지 코드에 적용시켜본 경험은 없다.