아이템 25 : 톱레벨 클래스는 한 파일에 하나만 담으라
1
2
3
4
5
|
public class Main {
public static void main(String[] args) {
System.out.println(Utensil.NAME + Dessert.NAME);
}
}
Colored by Color Scripter
|
이러한 메인 클래스가 존재할 때 Utensil와 Dessert 클래스가 Utensil.java라는 한 파일에 정의되어 있다고 가정해보자.
1
2
3
4
5
6
7
|
class Utensil {
static final String NAME = "pan";
}
class Dessert {
static final String NAME = "cake";
}
Colored by Color Scripter
|
main을 실행하면 pancake를 출력한다.
이제 우연히 똑같은 두 클래스를 담은 Dessert.java라는 파일을 만들었다고 가정해보자.
1
2
3
4
5
6
7
|
class Utensil {
static final String NAME = "pot";
}
class Dessert {
static final String NAME = "pie";
}
Colored by Color Scripter
|
main을 실행시 어떤 명령어로 실행하느냐에 따라 결과가 달라진다.
javac Main.java Dessert.java 명령으로 컴파일한다면 컴파일 오류가 나고 클래스를 중복 정의했다고 알려줄 것이다.
한편, javac Main.java나 javac Main.java Utensil.java 명령으로 컴파일하면 pancake를 출력하고, javac Dessert.java Main.java 명령으로 컴파일하면 potpie를 출력한다.
이러한 문제를 해결하는 방법은 간단하다. 톱레벨 클래스들을 서로 다른 소스 파일로 분리하면 된다.
한 파일에 담고 싶다면 정적 멤버 클래스를 사용하는 방법도 가능하다. 다른 클래스에 딸린 부차적인 클래스라면 정적 멤버 클래스로 만드는 쪽이 일반적으로 더 나을 것이다. 읽기 좋고, private로 선언하면 접근 범위도 최소로 관리할 수 있기 때문이다.
아래 코드는 정적 멤버 클래스로 변경한 코드이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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";
}
}
Colored by Color Scripter
|
핵심 정리
소스 파일 하나에는 반드시 톱레벨 클래스(혹은 톱레벨 인터페이스)를 하나만 담자. 이 규칙만 따른다면 컴파일러가 한 클래스에 대한 정의를 여러 개 만들어내는 일은 사라진다. 소스 파일을 어떤 순서로 컴파일하든 바이너리 파일이나 프로그램의 동작이 달라지는 일은 결코 일어나지 않을 것이다.
'언어 > JAVA' 카테고리의 다른 글
[Effective Java] 비검사 경고를 제거하라 (0) | 2020.03.22 |
---|---|
[Effective Java] 로 타입은 사용하지 말라 (0) | 2020.03.21 |
[Effective Java] 멤버 클래스는 되도록 static으로 만들라 (0) | 2020.03.20 |
[Effective Java] 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2020.03.20 |
[Effective Java] 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2020.03.19 |