맞는데 왜 틀릴까..?

Java/Effective Java

[Effective Java] Item 25. 톱레벨 클래스는 한 파일에 하나만 담으라

안도일 2023. 5. 8. 22:09

소스 파일 하나에 톱레벨 클래스를 여러 개 선언할 수 있지만 아무런 득이 없을뿐더러 심각한 위험을 감수해야 한다.

어느 소스 파일을 먼저 컴파일하냐에 따라 한 클래스를 여러 가지로 정의할 수 있기 때문이다.

 

아래에서 그 예를 살펴보자

 


Main

 

  • Main 클래스는 다른 톱레벨 클래스 2개(Utensil, Dessert)를 참조

 

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

 

Utensil.java

 

  • 두 클래스가 Utensil.java 한 파일에 정의

 

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

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

 

 

여기까지에서 Main을 실행하면 정상적으로 pancake가 출력된다.

 

 

Dessert.java

 

  • Utensil.java에서 정의된 똑같은 두 클래스가 Dessert.java에 정의

 

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

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

 

 

이 경우에 Main을 실행했을 때 어떻게 동작할까?

 

답은 "컴파일러에 어느 소스 파일을 먼저 건네느냐에 따라 동작이 바뀐다"이다

 

javac Main.java Dessert.java

Main에서 Utensil 참조를 먼저 만남 -> Utensil.java에서 Utensil과 Dessert를 확인함 -> Dessert.java 처리 -> 같은 클래스의 정의가 있음을 알게 됨

 

javac Main.java or javac Main.java Utensil.java -> pancake 출력 

 

javac Dessert.java Main.java -> potpie 출력

 

 


 

소스 파일 하나에는 반드시 톱레벨 클래스를 하나만 담자. 이 규칙을 따른다면 컴파일러가 한 클래스에 대한 정의를 여러 개 만들어 내는 일은 사라진다.

 

  • 톱레벨 클래스들을 서로 다른 소스 파일로 분리하자
  • 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하자