- 한 소스 파일에 톱 레벨 클래스를 여러개 선언하면 컴파일 순서에 따라 결과가 달라질 수 있다.
- 다른 클래스에 딸린 부차적인 클래스는 정적 멤버 클래스로 만드는 것이 낫다. 가독성이 좋으며 private로 선언해서 접근 범위도 최소한으로 관리할 수 있다.
소스파일 하나에 톱레벨 클래스를 여러개 선언하더라도 자바 컴파일러에서 오류를 뱉진 않지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 하는 행위이다.
이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 컴파일 시 각각의 .class파일로 분리가 되지만 그 중 어느것을 사용할지는 어느 소스 파일을 먼저 컴파일 하는가에 따라 달라지기 때문이다.
파일명은 Utensil.java 이지만 컴파일시 Utensil.class 파일과 Dessert.class 파일이 생성된다.
파일명이 Dessert.java이기 때문에 중복 파일 오류는 안나지만 역시 컴파일시 Utensil.class와 Dessert.class를 생성한다.
main 클래스가 Utensil과 Dessert 클래스를 참조한다.
그런데 어떤 Utensil과 Dessert 를 참조하게 될까?
우연히 똑같은 두 클래스를 담은 자바 파일을 만들었다고 했을 때 javac Main.java Dessert.java 명령으로 컴파일 한다면 컴파일 오류가 나고 Utensil과 Dessert 클래스를 중복 정의했다고 알려줄 것이다.
javac Main.java나 javac Main.java Utensil.java 명령으로 컴파일 하면 오류 없이 java Main을 실행하면 pancake를 출력한다. 그러나 javac Dessert.java Main.java 명령으로 컴파일 후 java Main을 실행하면 potpie를 출력한다. 이처럼 컴파일러에 어느 소스 파일을 먼저 건네느냐에 따라 동작이 달라지므로 반드시 바로잡아야 한다.
해결책인 단순히 톱레벨 클래스를 서로 다른 소스파일로 분리하면 그만이다.
굳이 여러 톱레벨 클래스를 한 파일에 담고싶다면 정적 멤버 클래스를 사용하는 방법을 고민해볼 수 있다. 어떤 클래스가 다른 클래스에 종속적이라면(부차적인 클래스라면) 정적 멤버 클래스로 만드는 쪽이 일반적으로 더 나을 것이다.
가독성도 좋고 private로 선언하면 접근 범위도 최소로 관리할 수 있기 때문에 더 났다.
소스 파일 하나에 반드시 톱레벨 클래스를 한 개만 담으면 어떤 순서로 컴파일 하든 바이너리 파일이나 프로그램의 동작이 달라지는 일은 결코 일어나지 않을 것이다.
내가 테스트 했을 땐 cmd 창에서 javac Main.java Dessert.java 명령어를 실행 했을 때 별다른 컴파일 오류가 나지 않고 .class 파일이 잘 만들어 졌다.
3개의 파일 모두 컴파일 했을 때만 중복 오류가 났다.
모쪼록 Utensil.java가 컴파일 되느냐 Dessert.java 가 컴파일 되느냐에 따라 실행되는 결과값이 달랐다.
한 파일에 톱레벨 클래스가 여러개일 경우 혹시 모르게 중복되는 톱레벨 클래스가 다른곳에서도 중첩으로 선언되었다면 내부 구현되있는 로직에 따라 동작이 달라질 수 있으므로 톱레벨 클래스들을 분리해야하고
굳이 중첩 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하는 방법을 고민해봐라.
https://www.inflearn.com/course/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94-2/dashboard
'개인룸 > 도윤' 카테고리의 다른 글
Item27. 비검사 경고를 제거하라 (0) | 2023.03.27 |
---|---|
Item26. 로타입은 사용하지 말라 (0) | 2023.03.26 |
Item24.멤버 클래스는 되도록 static으로 만들라 (0) | 2023.03.21 |
Item.23 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2023.03.20 |
22. 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2023.03.13 |