peaches-book-study / effective-java

이펙티브 자바 3/E
0 stars 2 forks source link

Item 25. 톱레벨 클래스는 한 파일에 하나만 담으라 #27

Open pyeong114 opened 4 months ago

pyeong114 commented 4 months ago

Chapter : 4. 클래스와 인터페이스

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

Assignee : eunpyeong114


🍑 서론

소스 파일 하나에 톱 레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않는다.

하지만 이는 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 하는 행위다.

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

🍑 본론

(예시) Main.java

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 = "pan";
}
class Dessert {
  static final String NAME = "cake";
}

컴파일 실행 순서에 따른 차이

javac Main.java Dessert.java 

위와 같이 컴파일한다면 Utensil과 Dessert 클래스가 중복 정의되었다는 컴파일 오류가 발생
why? 
1) javac Main.java : 컴파일러는 Main.java를 컴파일하고, 그 안에서 Utensil 참조를 만나 Utensil.java 파일을 살펴 Utensil과 Dessert를 모두 찾아냄
2) javac Dessert.java : Dessert.java를 처리하면서 이미 같은 클래스가 정의되어 있다 판단
javac Main.java or javac Main.java Utensil.java 

Dessert.java 파일을 작성하기 전처럼 pancake을 출력

이처럼 컴파일러에 어느 소스 파일을 먼저 건네느냐에 따라 동작이 달라진다

그렇기 때문에 이는 반드시 바로 잡아야 할 문제다!

해결책

단순히 톱레벨 클래스들을 서로 다른 소스 파일로 분리하면 된다.

굳이 여러 톱레벨 클래스를 한 파일에 담고 싶다면 정적 멤버 클래스를 사용하는 방법을 고민해볼 수도 있다

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

🍑 결론

소스 파일 하나에는 반드시 톱레벨 클래스(or 톱레벨 인터페이스)를 하나만 담자!


Referenced by

-