Contents
Item25. 톱레벨 클래스는 한 파일에 하나만 담으라
   Jan 6, 2023     3 min read

아이템 25. 톱레벨 클래스는 한 파일에 하나만 담아라

TL;DR

  • 한 소스파일에 톱레벨 클래스를 여러 개 선언하면 컴파일 순서에 따라 결과가 달라질 수 있다.
  • 다른 클래스에 딸린 부차적인 클래스는 정적 멤버 클래스로 만드는 것이 났고, 가독성이 좋고 private으로 선언해서 접근 범위도 최소한으로 관리할 수 있다.

자바 컴파일러는 하나의 소스파일에 톱레벨 클래스(가장 밖에 있는 클래스)를 여러개 선언하더라도 에러를 뱉어내지 않는다.

그러나

가독성 측면도 좋지않을 뿐만아니라, 심각한 위험을 감수해야한다.

하나의 소스파일에 여러 톱레벨 클래스를 선언하게 된다면 그 중 어느 것을 사용할지는 어떤 소스 파일을 먼저 컴파일 하냐에 따라 달라진다.

예제를 통해서 알아보자.

public class Main{
    public static void main(String[] args){
        System.out.println(Utensil.NAME + Dessert.NAME);
    }
}
  • 한 소스파일(Utensil.java)에 두개의 클래스가 있다.
class Utensil {
    static final String NAME = "pan";

}

class Dessert {
    static final String NAME= "cake";
}
  • 한 소스파일(Dessert.java)에 두개의 클래스가 있다.
class Utensil {
    static final String NAME = "pot";

}

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

동시에 컴파일 할 경우

두개 같이 동시에 컴파일한다면 duplicate class 에러가 난다.

Untitled


따로 컴파일을 할 경우

  • javac Main.java Utensil.java 할 경우
    • 결과 : pancake

Untitled 1

  • javac Main.java Dessert.java 할 경우
    • 결과 : potpie

Untitled 2

위 처럼 따로 컴파일 하는데 어느 것이 컴파일러에 먼저 순서가 가느냐에 따라서 동작이 달라진다.

따라서 컴파일 시점에서 문제가 생기기 때문에 조심해야할 문제다.

해결책

  • 톱레벨 클래스들(Utensil과 Dessert)을 서로 다른 소스 파일로 분리하라.

  • 굳이 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하는 방법을 고려해라.
    • 다른 클래스에 딸린 부차적인 클래스라면 정적 멤버 클래스로 만드는 방법이 더 나을 것이다. 왜냐하면 가독성이 좋고, private으로 선언하면 접근 범위도 최소로 관리할 수 있기 때문이다.
  • 톱레벨 클래들을 정적 멤버 클래스로 바꾼 예시
public class Test{
   public static void main(String[] args){
       System.out.println(Utensil.NAME + Dessert.NAME);
   }

  private static class Utensil {
      static final String NAME = "pen";

  }

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

}

💡결론 : 톱레벨 클래스는 한 파일에 하나만 담으라!