Study/Effective-Java

[item#25] 톱레벨 클래스는 한 파일에 하나만 담으라

hongeeii 2023. 11. 30. 10:51
728x90
반응형

톱레벨 클래스는 한 파일에 하나만 담으라

파일 하나에 톱레벨 클래스를 여러개 선언해도 컴파일은 됨

but 아무 이득이 없고 위험을 감수해야함.

(한 클래스를 여러가지고 정의할 수 있고, 그중 어느것을 사용할지는 컴파일 순서에 따라 달라짐)

// 예제
Main.java 파일

public class Main{
  public static void main(String[] args){
    System.out.print(Utensil.NAME + Dessert.NAME);
  }
}
Utensil.java 파일

class Utensil{
  static final String NAME = "pan";
}

class Dessert{
  static final String NAME = "cake";
}

이렇게 하면 pancake 이 출력되지만

우연히 Dessert.java 라는 파일에 똑같이 Utensil 과 Dessert를 정의하면

Dessert.java 파일

class Utensil{
  static final String NAME = "pot";
}

class Dessert{
  static final String NAME = "pie";
}

운좋게 javac Main.java Desert.java 로 컴파일하면 컴파일 오류가 나고 클래스를 중복 정의했다고 알려줌.

=> Utensil.java 를 먼저 살펴보고 Dessert.java 를 살펴보기 때문에 중복을 알아챔.

하지만 javac Main.java 나 javac Main.java Utensil.java 명령어로 컴파일하게 되면 pancake 을 출력함.

또 javac Desert.java Main.java 로 명령으로 컴파일하면 potpie 출력함.

이처럼 컴파일러에 어느 소스를 먼저 건네냐에 따라 동작이 달라짐.

  • 해결책

    톱레벨 클래스를 다른 소스파일로 분리하면 됨.

    굳이 톱레벨 클래스를 한파일 담고 싶으면 정적 멤버 클래스(item#24)를 사용해볼 수도 있음.

    다른 클래스에 따른 부차적인 클래스라면 정적 멤버 클래스로 만다는 쪽일 일반적으로 더 나음.

    => 읽기 좋고 private 으로 선언하면(item#15) 접근 범위도 최소로 관리할 수 있기 때문.

    ```java
    // 정적 멤버 클래스로 바꾼 예
    public class Test{
    public static void main(String[] args){
    System.out.println(Utensil.NAME + Dessert.NAME);
    }

    private static class Utensil{
    static final String NAME = "pan";
    }
    private static class Dessert{
    static final String NAME = "cake";
    }

}

728x90
반응형