소스 파일 하나에 톱레벨 클래스를 여러 개 선언할 수 있지만 아무런 득이 없을뿐더러 심각한 위험을 감수해야 한다.
어느 소스 파일을 먼저 컴파일하냐에 따라 한 클래스를 여러 가지로 정의할 수 있기 때문이다.
아래에서 그 예를 살펴보자
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 출력
소스 파일 하나에는 반드시 톱레벨 클래스를 하나만 담자. 이 규칙을 따른다면 컴파일러가 한 클래스에 대한 정의를 여러 개 만들어 내는 일은 사라진다.
- 톱레벨 클래스들을 서로 다른 소스 파일로 분리하자
- 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하자
'Java > Effective Java' 카테고리의 다른 글
[Effective Java] Item 27. 비검사 경고를 제거하라 (1) | 2023.05.09 |
---|---|
[Effective Java] Item 26. 로 타입은 사용하지 말라 (0) | 2023.05.09 |
[Effective Java] Item 24. 멤버 클래스는 되도록 static으로 만들라 (0) | 2023.05.05 |
[Effective Java] Item 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2023.05.05 |
[Effective Java] Item 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2023.05.03 |