[Java] Item 25 : 톱레벨 클래스는 한 파일에 하나만 담으라
Effective Java를 읽고 정리한 정리본입니다.
📌 Item 25 : 톱레벨 클래스는 한 파일에 하나만 담으라
소스파일 하나에 톱레벨 클래스가 여러 개 선언되어 있어도 컴파일 시 문제가 발생하지 않는다. 그러나 이런 식으로 정의 시 어느 소스 파일을 먼저 컴파일하냐에 따라 실행 결과가 달라지는 참사가 발생한다.
🫧 여러 개의 톱레벨 클래스 예시 코드
public class Main {
public static void main(String[] args) {
System.out.println(Utensil.NAME + Dessert.NAME);
}
}
해당 코드에서는 Main 클래스 하나가 다른 톱레벨 클래스 2개 (Utensil과 Dessert)를 참조하는 모습이다.
만일 집기 (Utensil)와 디저트 (Dessert) 클래스가 Utensil.java라는 하나의 파일에 정의되어 있다고 한다. 그렇다면 다음과 같은 코드가 나올 것이다. (안 좋은 예시로)
class Utensil {
static final String NAME = "pan";
}
class Dessert {
static final String NAME = "cake";
}
이 상태에서 Main을 실행한다면 pancake가 출력될 것이다.
그러나 이 상태에서 똑같은 두 클래스를 담은 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
or
javac Main.java Utensil.java
이렇게 컴파일하게 된다면 Dessert.java 파일을 작성하기 전처럼 pancake를 출력한다.
그러나 javac Dessert.java Main.java 명령으로 컴파일하면 potpie를 출력한다.
🫧 문제 해결법
단순히 톱레벨 클래스들 (Utensil과 Dessert) 를 서로 다른 소스 파일로 분리하면 이러한 문제는 손쉽게 해결된다.
다음 코드는 앞의 예를 정적 멤버 클래스로 바꿔본 예이다.
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";
}
}
여러 톱레벨 클래스를 한 파일에 담고 싶을 때는 정적 멤버 클래스를 사용할 수 있다.