작성자 없음
작성자 정보가 삭제된 글입니다.
작성
·
823
2
안녕하세요! 강의 너무나 잘 듣고 있습니다.
public class Settings {
private Settings() {
}
private static class SettingsHolder {
private static final Settings INSTANCE = new Settings();
}
public static Settings getInstance() {
return SettingsHolder.INSTANCE;
}
}
로드 시점에 관한 질문입니다. getInstance가 호출 될때 SettingsHolder가 JVM에 로드된다고 말씀하셨습니다. 자바는 잘 모르지만, 동적으로 로드가 된다고 해석했습니다.
public class Settings {
private static final Settings INSTANCE = new Settings();
private Settings() {
}
public static Settings getInstance() {
return INSTANCE;
}
}
그렇다면 이른 초기화 방식도, 마치 SettingsHolder가 그러하듯, 필요로 할 때 동적으로 로드 될 순 없나요? 필요로 할 때 로드된다면 SettingsHolder를 필요로 하지 않을 테니 말이죠.
그럼에도 불구하고 static inner class를 사용하는 건 반드시 이유가 있을 테니.. 하여 제 나름대로 찾아보고 테스트해 본 결과 자바 파일에 정의된 기본 클래스들은 실행 시 로드됨을 확인했습니다. 모든 클래스가 실행 시 로드되는진 확실하진 않지만 이와 관련된 JVM의 로드 정책에 대해서 간략하게 설명 부탁드립니다. :)
답변 3
7
Settings에 getInstance()라는 static 메소드 말고 다른 메소드도 있다고 가정을 하고 생각해 보시면 어떤 차이가 있는지 이해할 수 있을 것 같습니다. 편의상 Settings를 A, 그 안에 들어있는 홀더를 B라고 했을 때 B는 A가 아무리 사용되더라도 로딩이 되지 않고 오로지 A에서 getInstance를 호출했을 때 그때 B의 인스턴스를 만들게 되니까 초기화 지연 기법이라고 한 것입니다.
그리고 초기화 지연 기법이 의미가 있으려면 그렇게 생성하는 인스턴스가 생성하는데 오래 걸리거나, 많은 리소스를 필요로 하는 경우인데 위의 예제에선 오히려 코드만 복잡하게 할 뿐 Holder를 쓰지 않아도 됩니다.
저 역시 홀더가 반드시 좋다고 설명한 수업이 아닙니다. 초기화 지연 기법이 필요하다면 그렇게 할 수도 있다고 설명한거죠.
"그렇다면 아래와 같이 Holder를 사용하지 않는 싱글톤 구현 클래스또한 "최초로 사용될 때" 로딩되므로 이른 초기화라고 말할 수 있나요?" 네 해당 코드는 이른 초기화가 맞긴 한데 "최초로 사용될 때" 로딩되기 때문이 아니라.. 해당 클래스가 로딩 되는 시점에 인스턴스가 생기기 때문이죠.
홀더를 사용한 코드가 초기화 지연 기법인 이유는 A라는 클래스가 또다른 static 메소드를 호출 할 때 이미 로딩이 됐더라도, A라는 타입의 인스턴스는 생기지 않고, 오직 getInstance가 호출 됐을 때 B라는 홀더가 로딩되면서 그 안에서 A인스턴스가 생기기 때문입니다. A 클래스가 로딩 될 때가 아니라 이미 로딩된 다음에 나중에 A 인스턴스가 생겼으니까요.
그런데 다시 말하지만, 홀더가 항상 좋다고 설명한 것도 아니고 그냥 이런 특징이 있으니 필요한 경우엔 이렇게 쓸 수도 있다는 것입니다.
1
"관심사 밖이다"라는 표현이 어떤 뜻인지 잘 모르겠지만, 내부 정적 클래스도 다른 클래스와 마찬가지로 최초로 사용이 될 때 로딩이 됩니다.
2번 질문에 대해서는 다시 또 classpath에 대해 학습하시고 글을 남기시면 리뷰해 드리겠습니다. 구체적으로 클래스패스란 무엇이며 어떻게 설정하는지 학습하시면 될 것 같습니다.
1