JAVA/Effective Java

[아이템 25] 톱레벨 클래스는 한 파일에 하나만 담으라

꾸준함. 2024. 2. 9. 00:39

하나의 소스 파일에 여러 개의 톱레벨 클래스를 선언해도 컴파일 에러는 발생하지 않지만, 이러한 구현은 혜택이 없을 뿐만 아니라 심각한 위험을 초래할 수 있습니다.

  • 한 소스 파일에 톱 레벨 클래스를 여러 개 선언할 경우 컴파일 순서에 따라 결과가 달라질 수 있음

 

구체적인 예를 보면 아래와 같습니다.

다음과 같이 톱 레벨 클래스인 Utensil과 Dessert를 참조하는 Main 클래스가 있습니다.

 

 

Utensil.java 파일에 다음과 같이 Utensil과 Dessert 클래스가 정의되어 있을 경우 Main 클래스를 실행할 경우 pancake를 출력합니다.

 

 

이 상태에서 우연히 똑같은 두 클래스를 다음 Dessert.java 파일을 생성했을 경우 명령어에 따라 다른 상황이 발생할 수 있습니다.


 

1. javac Main.java Dessert.java 명령으로 컴파일

 

javac Main.java Dessert.java 명령으로 컴파일할 경우 컴파일 오류가 발생하고 Utensil과 Dessert 클래스가 중복 정의했다고 알려줍니다.

컴파일러는 가장 먼저 Main.java를 컴파일하고 그 안에서 Dessert 참조보다 먼저 나오는 Utensil 참조를 만나면 Utensil.java 파일을 살펴 Utensil과 Dessert를 모두 찾아낼 것입니다.

 

2. javac Main.java 혹은 javac Main.java Utensil.java 명령으로 컴파일

 

위 명령어로 컴파일 할 경우 앞선 예제처럼 pancake를 출력합니다.

 

3. javac Dessert.java Main.java 명령으로 컴파일

 

위 명령어로 컴파일 할 경우 pancake이 아닌 potpie를 출력합니다.

이처럼 컴파일러에 어떤 소스 파일을 먼저 전달하느냐에 따라 동작이 달라지기 때문에 한 파일에 다수의 톱 레벨 클래스를 정의하는 것은 피해야 합니다.

 

해결책

앞서 언급한 문제에 대한 해결책은 탑 레벨 클래스를 서로 다른 소스 파일로 분리하는 것입니다.

굳이 여러 톱 레벨 클래스를 하나의 파일에 담고 싶다면, 아이템 24에서 언급한 대로 정적 멤버 클래스를 사용하는 것을 권장합니다.

정적 멤버 클래스로 선언할 경우 가독성이 좋아지고 private으로 선언할 경우 접근 범위도 최소로 관리할 수 있기 때문입니다.


 

정리

톱 레벨 클래스는 한 파일에 하나만 담는 것이 권장됩니다.

이 규칙을 따를 경우, 소스 파일을 어떤 순서로 컴파일하더라도 바이너리 파일이나 프로그램의 동작이 달라지지 않을 것입니다.

 

참고

이펙티브 자바
이펙티브 자바 완벽 공략 2부 - 백기선 강사님

반응형