glenn-syj / more-effective-java

이펙티브 자바를 읽으며 자바를 더 효율적으로 공부합니다
4 stars 5 forks source link

[MEJ-006] 톱레벨 클래스가 여러개 존재할 때에 대한 이해 #136

Closed undeadtimo closed 3 months ago

undeadtimo commented 4 months ago

Based on : @FickleBoBo by #125

톱레벨 클래스에 대한 탐구를 진행한 FickleBoBo님의 글 잘 읽었습니다.

각 IDEA에서 톱레벨 클래스가 여러 존재하는 파일에서의 반응을 확인하는 것이 흥미로웠습니다.

저 또한 FickleBoBo님이 말씀하신 결과가 동일하게 출력되는지 STS에서 확인해보았습니다.

Main이름의 자바파일을 생성 후, 마찬가지로 두 개의 Utensil과 두 개의 Dessert 클래스를 작성하고, Main 클래스 내부에서 main을 통해 어떤 클래스의 변수가 출력이 될지 확인하기 위해 class 파일을 실행하였습니다.

package top;

class Utensil {
    static final String NAME = "pan";
}

class Dessert {
    static final String NAME = "cake";
}

class Utensil {
    static final String NAME = "pot";
}

class Dessert {
    static final String NAME = "pie";
}
public class Main {
    public static void main(String[] args) {
        System.out.println(Utensil.NAME + Dessert.NAME);
    }
}

그러면 오류 메시지가 발생하긴 하지만, 위에 먼저 작성되어있는 두 클래스의 변수값이 출력되고 있는 것을 확인할 수 있었습니다.

이후, FickleBoBo님이 확인하지 못한 터미널에서의 중복 클래스가 존재하는 파일 실행 결과를 확인해보았습니다.

Main.java:11: error: duplicate class: top.Utensil
class Utensil {
^
Main.java:15: error: duplicate class: top.Dessert
class Dessert {
^
2 errors

FickleBoBo님께서 직접 수행한 과정들을 따라하니, 톱레벨 클래스를 하나만 두는 것을 권장하는 이유를 더욱 실감할 수 있었습니다.

FickleBoBo commented 4 months ago

개인 PC에서 터미널로 확인하지 못해 아쉬운 점이 있는 글이었는데 테스트를 통해 보충해주셔서 감사합니다. 교육용 PC에서는 터미널로 출력이 가능해서 저 역시 교재와 동일한 환경에서 테스트하고 몇가지 출력 결과를 확인할 수 있었습니다.

총 6가지 상황을 예상해보고 테스트를 진행했으며 해당 결과를 통해 본 글에서 chatGPT를 통해 얻었던 출력 규칙 아이디어에 대한 실험적 검증을 해보려고 했습니다.

다음 코드에서 ->는 다음 줄에 작성했다는 의미이고 =는 터미널 출력 결과를 의미합니다.

  1. javac Utensil.java Main.java -> java Main = potpie Utensil.java의 Name인 pot과 pie가 출력됐습니다.

  2. javac Dessert.java Main.java -> java Main = pancake Dessert.java의 Name인 pan과 cake가 출력됐습니다.

  3. javac Dessert.java Utensil.java Main.java = duplicate class error 발생

  4. javac Dessert.java -> javac Utensil.java -> javac.Main.java -> java Main = potpie Utensil.java의 Name인 pot과 pie가 출력됐습니다.

  5. javac Utensil.java Dessert.java Main.java = duplicate class error 발생

  6. javac Utensil.java -> javac Dessert.java -> javac Main.java -> java Main = pancake Dessert.java의 Name인 pan과 cake가 출력됐습니다.

다음 결과를 통해 javac에서 한 줄로 관련 클래스 전체를 컴파일 하려고 할 경우 중복 클래스에 대한 에러를 잡아내는 것으로 보였으며, 클래스를 하나씩 javac 으로 컴파일 할 경우 동일한 이름의 클래스가 있을 경우 가장 최근에 컴파일 된 클래스가 덮어지는 것처럼 보였습니다.

undeadtimo commented 4 months ago

클래스를 하나씩 컴파일하여 실행하는 것은 생각하지 못했었는데, 마지막으로 컴파일 된 클래스가 덮어씌워지는 결과가 흥미롭게 느껴지는군요.

저의 질문에 추가적인 탐구를 통해 답변을 해주셔서 감사드립니다.