ITEM 25 "탑 레벨 클래스는 한 파일에 하나만 담으라"
소스 파일 하나에 탑 레벨 클래스를 여러 개 선언해도 자바 컴파일러는 에러를 발생시키진 않는다.
하지만 아무런 득이 없고, 심각한 위험을 감수해야 한다. 한 파일에 여러 클래스를 정의하는데 다른 파일에서도 같은 클래스를 정의할 수 있기 때문에 어느 소스 파일을 먼저 컴파일하느냐에 따라 다른 로직이 수행될 수 있다.
public class Utensil {
static final String NAME = "pan";
}
public class Dessert {
static final String NAME = "cake";
}
Utensil.java
public class Utensil {
static final String NAME = "pot";
}
public class Dessert {
static final String NAME = "pie";
}
Dessert.java
public class Main {
public static void main(String[] args) {
System.out.println(Utensil.NAME + Dessert.NAME);
}
}
Main.java
Utensil.java 및 Dessert.java 파일에 같은 클래스가 정의되었을 때 어떤 순서대로 컴파일하느냐에 따라 결과가 달라진다.
예를 들어, "javac Main.java Dessert.java" 명령으로 컴파일한다면 컴파일 오류가 난다. 가장 먼저 Main.java 를 컴파일하고, 그 안에서 Utensil 참조를 만나 Utensil.java 파일을 살펴 Utensil 과 Dessert 를 모두 가져온다. 그리고 나서 두 번째 명령줄 인수인 Dessert.java 를 처리하려고 할 때 같은 클래스에 대한 정의가 이미 있어 컴파일 오류가 나는 것이다.
"javac Main.java" 나 "javac Main.java Utensil.java" 명령으로 컴파일하면 Dessert.java 참조가 없기 때문에 "pancake" 를 출력한다. 반대로 "javac Dessert.java Main.java" 명령으로 컴파일하면 "potpie" 를 출력한다.
컴파일 순서에 따라 결과가 달라지는 문제를 해결하려면, 단순히 탑 레벨 클래스들을 서로 다른 소스 파일로 분리하면 된다. 굳이 여러 탑 레벨 클래스를 한 파일에 담고 싶다면, 정적 멤버 클래스를 고민해보는 것이 좋을 수 있다.
Intellij 에서 자바 파일 이름과 다른 클래스가 탑 레벨로 생기면 알아서 아래처럼 경고문구가 발생하면서 컴파일이 되지 않는다. "Class xxxx is public, should be declared in a file named '자바 이름'.java"
그래서 이번 아이템은 솔직히 강제로 지킬 수 있어 걱정 안해도 될 것 같다. ^^
'독후감 > Effective JAVA' 카테고리의 다른 글
[Effective JAVA] 27 "비검사 경로를 제거하라" (0) | 2022.05.24 |
---|---|
[Effective JAVA] 26 "로 타입은 사용하지 말라" (0) | 2022.05.23 |
[Effective JAVA] 24 "멤버 클래스는 되도록 static 으로 만들어라" (0) | 2022.05.20 |
[Effective JAVA] 23 "태그 달린 클래스보다는 클래스 계층구조를 활용하라" (0) | 2022.05.18 |
[Effective JAVA] 22 "인터페이스는 타입을 정의하는 용도로만 사용하라" (0) | 2022.05.17 |