소스 파일 하나에 여러 개의 톱레벨 클래스
를 선언하더라도 자바 컴파일러는 불평하지 않는다.
하지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 한다.
한 클래스를 여러 가지로 정의할 수 있으며, 그 중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하느냐에 따라 달라지기 때문이다.
Main.java
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";
}
Dessert.java
// 두 클래스가 한 파일(Dessert.java)에 정의되었다. - 따라 하지 말 것!
class Utensil {
static final String NAME = "pot";
}
class Dessert {
static final String NAME = "pie";
}
javac Main.java Dessert.java
로 컴파일하는 경우
컴파일 오류. Utensil과 Dessert 클래스 중복 정의.
javac Main.java
혹은 javac Main.java Utensil.java
로 컴파일하는 경우
pancake 출력.
javac Dessert.java Main.java
로 컴파일하는 경우
potpie 출력.
해결책은 2가지가 있다.
1️⃣ 톱레벨 클래스(Utensil, Dessert)들을 서로 다른 소스 파일로 분리
한다.
2️⃣ 정적 멤버 클래스
를 사용한다.
// 톱레벨 클래스들을 정적 멤버 클래스로 바꿔본 모습
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";
}
}
📌 핵심 정리
소스 파일 하나에는 반드시 톱레벨 클래스 (혹은 톱레벨 인터페이스)를 하나만 담자.