IT Share you

.class가 클래스의 정적 블록을 호출하지 않는 이유는 무엇입니까?

shareyou 2020. 11. 8. 11:32
반응형

.class가 클래스의 정적 블록을 호출하지 않는 이유는 무엇입니까?


이것은 내가 가진 코드입니다.

public class StupidClass {
    static {
        System.out.println("Stupid class loaded!");
    }
}

그리고 내가 가진 테스트는 따로 실행 합니다 .

import org.junit.Test;

public class StupidTest {
    @Test
    public void foo() throws ClassNotFoundException {
        final Class<?> stupidClass = Class.forName("StupidClass");
        System.out.println(stupidClass.getSimpleName());
    }

    @Test
    public void bar() throws ClassNotFoundException {
        final Class<StupidClass> stupidClassClass = StupidClass.class;
        System.out.println(stupidClassClass.getSimpleName());
    }
}

테스트 foo를 실행하면 다음과 같이 표시됩니다.

Stupid class loaded!
StupidClass

하지만 테스트 바를 실행하면 다음과 같이 표시됩니다.

StupidClass

페이지 에서 인용 ..

클래스 객체는 클래스가로드 될 때 Java Virtual Machine에 의해 그리고 클래스 로더에서 defineClass 메소드에 대한 호출에 의해 자동으로 구성됩니다.

그래서 내 이해는 테스트 바에서 Stupid 클래스가로드되었습니다. 그렇지 않으면 null을 보았을 것입니다. 그래서 클래스 자체가로드되어 클래스 객체가 생성됩니다.

그리고 지금에서 인용 페이지

정적 초기화 블록은 JVM (구체적으로는 클래스 로더)이 StaticClass를로드 할 때 실행됩니다 (코드에서 처음 참조 될 때 발생 함).

그래서 "Stupid class loaded!" 테스트 바의 텍스트도 있지만 그렇지 않습니다.

또한 Thinking in Java 에서 인용

Candy, Gum 및 Cookie 클래스 각각에는 클래스가 처음로드 될 때 실행되는 정적 절이 있습니다.

그다지 정확하지 않은 것 같습니다 ..

내가 무엇을 놓치고 있습니까?


정적 초기화 블록은 JVM (구체적으로는 클래스 로더)이 StaticClass를로드 할 때 실행됩니다 (코드에서 처음 참조 될 때 발생 함).

위의 인용문은 명백히 잘못되었지만 매우 널리 퍼진 오해의 한 예일뿐입니다.

  1. 클래스 로드 될 때 초기화되지 않지만 정적 클래스 멤버 가 처음 참조 될 때 초기화 됩니다 . 이것은 사양 에 의해 정확하게 관리됩니다 .

  2. 클래스 로딩 클래스가 처음 참조 될 때 발생하지 않지만 구현 종속 지점에서 발생합니다.

  3. 클래스를로드해야하는 마지막 순간은 클래스가 참조 될 때 입니다. 이는 클래스 멤버 를 참조하는 것과 다릅니다 .

Class.forName기본적으로 클래스를 초기화하지만를 가져와 boolean initialize제공 하는 오버로드를 호출 할 수 있습니다 false. 초기화하지 않고 클래스를로드 할 수 있습니다.


클래스 로딩과 초기화는 서로 다른 두 가지입니다. 클래스를로드 할 수 있지만 실제로 필요할 때까지 초기화 할 수 없습니다. 정적 이니셜 라이저는 클래스가 초기화 될 때만 실행됩니다. <>로드되지 않고 "초기화 됨"

첫 번째 경우를 사용할 때 클래스를로드하고 초기화하는 class.forName()것이므로 정적 이니셜 라이저가 실행되므로 "Stupid class loaded!"출력으로 표시 됩니다. 두 번째 경우에는 클래스의 참조를 할당 하고 클래스가로드 되지만 (어떤 클래스가로드되는지 확인하려면 java -verbose : class 사용) 실제로 초기화하지 않습니다 (또는 더 정확하게 말하자면 수행하지 않음). 이니셜 라이저를 강제 실행하는 모든 것). 따라서 출력이 Stupid class loaded!. newInstance()클래스를 호출하는 것과 같은 작업을 시도 하면 클래스 초기화가 강제 실행되고Stupid class loaded!

내 코드 :

public class CheckPalindrome {

    public static void main(String[] args) {
        Class<Test> t = Test.class;
    }

}
// class being loaded
class Test {
    static {
        System.out.println("aaa");
    }
}

로드 된 클래스

...
[Loaded Test from file:/Workspaces/SampleTest/Java8/bin/]
...

^-클래스가로드되었지만 초기화되지 않았 음을 나타냅니다.

참고URL : https://stackoverflow.com/questions/39504847/why-does-class-not-invoke-the-static-block-in-a-class

반응형