JAVA/Effective Java

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

IT-사과 2022. 6. 11. 13:39

소스 파일 하나에 톱레벨 클래스를 여러 개 선언할 수는 있지만, 아무런 득이 없고 심각한 위험을 감수해야하는 행위다.

이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 그중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하냐에 따라 달라지기 때문이다. 

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 명령으로 컴파일한다면 컴파일 오류가 나고 Dessert와 Utensil 클랫를 중복 정의했다고 알려 줄 것이다. 컴파일러는 가장 먼저 Main.java를 컴파일하고, 그 안에서 Utensil 참조를 만나면 Utensil.java 파일을 살펴  Utensil과 Dessert를 모두 찾아낼 것이다. 그런 다음 컴파일러가 두 번째 명령줄 인수로 넘어온 Dessert.java를 처리하려 할때 같은 클래스의 정의가 이미 있음을 알게된다.

javac Main.java
javac Main.java Utensil.java
//pankake 출력
javac Dessert.java Main.java
//potpie 출력

톱레벨 클래스들(Utensil과 Dessert)을 서로 다른 소스 파일로 분리하면 문제 해결이 가능하다,

굳이 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용할 수도 있다.

읽기 좋고 private으로 선언하면 접근 범위도 최소로 관리할 수 있기 때문이다.

 

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";
    }
}

참고자료

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=

 

이펙티브 자바 3/E - 교보문고

프로그래밍인사이트 | 자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브러리의 최신 기능을 십분 활용

www.kyobobook.co.kr