-
item 25 톱 레벨 클래스는 한 파일에 하나만 담으라책/이펙티브 자바 2022. 3. 15. 22:46
ITEM 25 톱 레벨 클래스는 한 파일에 하나만 담으라
소스 파일 하나에 톱레벨 클래스를 많이 선언해도 컴파일에 문제는 없지만 아무 의미가 없고 위험만 증가한다
- 한 클래스를 여러가지로 정의가 가능해지고 어느게 사용되는지는 컴파일 순서에 따라 달라지기 때문이다
public class Main { public static void main(String[] args) { System.out.println(Utensil.NAME + Dessert.NAME); } }
Utensil.java class Utensil { static final String NAME = "pan"; } class Dessert { static final String NAME = "cake"; }
Dessert.java class Utensil { static final String NAME = "pot"; } class Dessert { static final String NAME = "pie"; }
위 같은 코드를 작성한다면 컴파일러에 어느 소스 파일을 먼저 보내느냐에 따라 결과값이 다르게 나타난다
javac Main.java Dessert.java 명령으로 컴파일시 컴파일 오류가 나면서 Utensil과 Dessert 클래스를 중복으로 사용했다고 알려줄것이다
컴파일러는 먼저 Main.java를 컴파일하고 그 안에서 Dessert 참조보다 먼저 나오는 Utensil 참조를 만나면 Utensil.java 파일 안에서 Utensil과 Dessert를 찾을것이다
그 다음 두번째 명령의 인수인 Dessert.java를 처리하려고 할때 같은 클래스가 이미 정의되어 있다는 것을 알게된다
javac Main.java나 javac Main.java Utensiljava 명령으로 컴파일 하면 Dessert.java 파일을 작성하기 전처럼 pancake를 출력한다
javac Dessert.java Main.java 명령으로 컴파일 하면 potpie를 출력한다
결국 결과값이 달라지는 심각한 오류가 발생할 가능성이 있으니 톱레벨 클래스들이 한 파일에 여러개 있다면 분리를 시켜줘야 한다
다른 파일로 분리를 시키는 방법도 있고 한 파일에 담는 방법을 계속 사용하고 싶다면 정적 멤버 클래스를 만들어서 사용하자
public class Test { public class Main { 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"; } }
소스 파일 하나에는 반드시 톱레벨 클래스나 톱레벨 인터페이스를 하나만 만들자
이 규칙을 따른다면 소스 파일의 컴파일 순서와 관계 없이 바이너리 파일이나 프로그램이 달라지는 경우는 없을것이다
'책 > 이펙티브 자바' 카테고리의 다른 글
item 27 비검사 경고를 제거하라 (0) 2022.03.17 item 26 로 타입은 사용하지 말라 (0) 2022.03.16 item 24 멤버 클래스는 되도록 static으로 만들라 (0) 2022.03.14 item 23 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) 2022.03.14 item 22 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) 2022.03.10