[item#25] 톱레벨 클래스는 한 파일에 하나만 담으라
톱레벨 클래스는 한 파일에 하나만 담으라
파일 하나에 톱레벨 클래스를 여러개 선언해도 컴파일은 됨
but 아무 이득이 없고 위험을 감수해야함.
(한 클래스를 여러가지고 정의할 수 있고, 그중 어느것을 사용할지는 컴파일 순서에 따라 달라짐)
// 예제
Main.java 파일
public class Main{
public static void main(String[] args){
System.out.print(Utensil.NAME + Dessert.NAME);
}
}
Utensil.java 파일
class Utensil{
static final String NAME = "pan";
}
class Dessert{
static final String NAME = "cake";
}
이렇게 하면 pancake 이 출력되지만
우연히 Dessert.java 라는 파일에 똑같이 Utensil 과 Dessert를 정의하면
Dessert.java 파일
class Utensil{
static final String NAME = "pot";
}
class Dessert{
static final String NAME = "pie";
}
운좋게 javac Main.java Desert.java 로 컴파일하면 컴파일 오류가 나고 클래스를 중복 정의했다고 알려줌.
=> Utensil.java 를 먼저 살펴보고 Dessert.java 를 살펴보기 때문에 중복을 알아챔.
하지만 javac Main.java 나 javac Main.java Utensil.java 명령어로 컴파일하게 되면 pancake 을 출력함.
또 javac Desert.java Main.java 로 명령으로 컴파일하면 potpie 출력함.
이처럼 컴파일러에 어느 소스를 먼저 건네냐에 따라 동작이 달라짐.
해결책
톱레벨 클래스를 다른 소스파일로 분리하면 됨.
굳이 톱레벨 클래스를 한파일 담고 싶으면 정적 멤버 클래스(item#24)를 사용해볼 수도 있음.
다른 클래스에 따른 부차적인 클래스라면 정적 멤버 클래스로 만다는 쪽일 일반적으로 더 나음.
=> 읽기 좋고 private 으로 선언하면(item#15) 접근 범위도 최소로 관리할 수 있기 때문.
```java
// 정적 멤버 클래스로 바꾼 예
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";
}
}