반응형
이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.
아이템 25. 톱레벨 클래스는 한 파일에 하나만 담으라
톱레벨 클래스
- 소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 컴파일러에서 오류는 발생하지 않지만, 아무런 득이 없고 심각한 위험을 감수해야 한다.
- 이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 그 중 어느 것을 사용할 지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라진다.
ex 1) Main 클래스 하나를 담고 있고 Main 클래스는 다른 톱레벨 클래스 2개(Utensil과 Desser)를 참조한다.
public class Main {
public static void main(String[] args) {
System.out.println(Utensil.NAME + Dessert.NAME);
}
}
ex 2) 집기(Utensil)와 디저트(Desser) 클래스가 Utesnil.java 라는 한 파일에 정의된 소스
class Utensil {
static final String NAME = "cup";
}
class Dessert {
static final String NAME = "cake";
}
위의 Main을 실행하면 cupcake가 출력된다.
이 때, Dessert.java 파일에 위와 같은 소스가 정의된다고 가정해보자.
ex 3) Dessert.java 파일에 두 클래스가 정의된 소스
class Utensil {
static final String NAME = "cup";
}
class Dessert {
static final String NAME = "bbokki";
}
// 순서에 따라 실행 결과가 달라진다.
javac Main.java // cupcake 출력
javac Main.java Utensil.java // cupcake 출력
javac Dessert.java Main.java // cupbbokki 출력
이렇게 Utensil.java 파일에 있는 똑같은 클래스를 중복 정의했을때 컴파일러의 동작에 따라 결과가 달라지므로 문제가 발생한다.
즉, 컴파일러에 어느 소스파일을 먼저 건네느냐에 따라서 정상 동작할수도 또는 컴파일 오류가 발생할 수도 있다.
해결 방법
- 톱레벨 클래스들을 서로 다른 소스 파일로 분리한다.
- 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하자.
ex 4) 톱레벨 클래스들을 정적 멤버 클래스로 변경한 소스
public class Test {
public static void main(String[] args) {
System.out.println(Utensil.NAME + Dessert.NAME);
}
private static class Utensil{
static final String NAME = "cup";
}
private static class Dessert{
static final String NAME = "cake";
}
}
정리
소스 파일 하나에는 톱레벨 클래스(혹은 톱레벨 인터페이스)를 반드시 하나만 담자.
반응형
'BE > Java' 카테고리의 다른 글
[Effective Java] 아이템 27. 비검사 경고를 제거하라 (0) | 2022.10.07 |
---|---|
[Effective Java] 아이템 26. 로 타입은 사용하지 말라 (0) | 2022.10.06 |
[Effective Java] 아이템 24. 멤버 클래스는 되도록 static으로 만들라 (0) | 2022.10.04 |
[Effective Java] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (1) | 2022.09.30 |
[Effective Java] 아이템 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.09.29 |