class AAA {
static {
System.out.println("class AAA static block println"); // 并没有打印此句
}
}
public class Main {
public static void main(String[] args) {
System.out.println("hello world!");
}
}
一直以来都以为 static 标识的代码块或者是字段,都是在类加载的时候就被执行或者赋值了,但是这么一看....感觉自己的世界观都要被刷新了。
所以此处是类没有被加载吗?还是说我们一直以来认为的,静态代码块、字段都在类加载的时候被初始化的,这个观点是错误的?
在《深入理解Java虚拟机:JVM高级特性与最佳实践 第2版》中找到一些线索,如下图:
所以,照这么说,是在第一次主动访问该类的时候执行?小弟好生迷惑啊....大家快说说你们的观点
ringa_lee2017-04-18 10:54:20
클래스 초기화 및 객체 초기화.
static에 포함된 코드 블록과 변수는 클래스가 초기화될 때만 실행되며, 초기화를 위한 5가지 조건도 알고 있습니다.
명확하게 설명해 주세요.
우선 동일한 .java 파일에 넣어도 컴파일 후에도 여전히 두 개의 다른 클래스 파일입니다. 믿을 수 없다면 해당 하위에 생성된 .class 파일을 살펴보세요. 빈 패키지.
둘째, 클래스가 초기화되면 클래스의 정적 변수가 초기화되고 정적 코드 블록이 실행됩니다. 따라서 가상머신은 new, getstatic, putstatic 명령어의 사용, 메인 함수가 위치한 클래스, 리플렉션, 상위 클래스 등 5가지 초기화 조건을 규정한다. 그러나 이러한 다섯 가지 상황을 제외하고는 클래스 초기화가 트리거될 수 없습니다. 코드에 표시된 것처럼 Main.class에는 호출이나 상위-하위 관계 또는 AAA.class에 대한 반영이 없습니다. 따라서 AAA.class는 당연히 초기화되지 않습니다.
Java 클래스 로딩 과정에 대한 다른 블로그를 읽어보실 수 있습니다
이해하셨나요?
PHP中文网2017-04-18 10:54:20
여기서 다루어야 할 두 가지 개념이 있습니다.
클래스 로딩 메커니즘
Java, 컴파일러, 바이트코드, JVM 사양 및 구현.
클래스 로딩은 클래스 로더(Classloader)를 통해 완료됩니다. 구체적인 로딩 전략은 JVM의 구체적인 구현에 따라 다릅니다. 일반적으로 두 가지 유형으로 나눌 수 있습니다.
다른 클래스에서 참조하는 한 로딩이 필요합니다.
지연 로딩, 클래스에 액세스할 때 로딩.
Java, 컴파일러, 바이트코드 및 JVM에는 고유한 사양이 있으며 사양을 통해 함께 작동합니다.
컴파일 버튼은 Java 코드를 표준화된 바이트코드 파일로 컴파일합니다. 각 클래스(외부 클래스, 내부 클래스, 익명 클래스)는 별도의 바이트코드 파일(클래스 파일)로 컴파일되며 이때 JVM은 클래스를 로드합니다. , 이러한 클래스 파일에서 하나씩 로드됩니다.
이제 코드로 돌아갑니다.
Java 계층에서는 AAA와 Main 두 클래스를 하나의 파일에 넣습니다. 컴파일 후 컴파일러는 AAA.class와 Main.class라는 두 개의 클래스 파일을 생성합니다.
두 클래스는 코드 구성 측면에서 함께 있지만 컴파일 후에는 독립적이며 Main은 AAA를 참조하지 않으므로 어떤 클래스 로딩 방법을 사용하더라도 클래스 AAA 로딩을 트리거하지 않습니다. AAA의 정적 코드 블록은 실행되지 않습니다.
ringa_lee2017-04-18 10:54:20
답변해주신 위 열정적인 네티즌분들께 진심으로 감사드립니다!
AAA 클래스는 실제로 로드되지 않고 Main 클래스만 로드됩니다. (질문의 스크린샷: 네 번째 초기화 조건, 메인 클래스는 jvm에 의해 자동으로 로드됩니다.)
으아악클래스의 정적 필드 | 코드 블록은 클래스가 로드될 때 실제로 초기화되거나 실행됩니다!
확장 명령이 실행되는 한 클래스가 jvm에 의해 로드될 것이라고 생각했습니다. 실제로는 그렇지 않습니다. 명령은 javac
파일을 jvm이 이해할 수 있는 .java
파일로만 변환합니다. .class
그럼 클래스가 jvm에 의해 로드되었는지 어떻게 알 수 있나요? "Java Virtual Machine에 대한 심층적인 이해: JVM 고급 기능 및 모범 사례 2판"과 네티즌들의 열광적인 답변에 따르면 언제 로드될지 명확한 시기가 정해지지 않았습니다!
에서는 클래스가 초기화되는 시점을 명확하게 규정하고 있습니다 - 위 스크린샷에는 4가지 타입이 있습니다! 클래스 로딩은 클래스 초기화보다 우선하므로 여기서는 일시적으로 이러한 상황이 클래스 로딩을 트리거하는 조건이라고 생각할 수 있습니다.
오빠가 무식해서 부적절한 내용을 요약했네요 정정해주세요! 감사합니다大家讲道理2017-04-18 10:54:20
메인 메서드가 실행되면 Main 클래스만 로드됩니다. Main 클래스에서는 AAA 클래스가 사용되지 않으며 AAA 클래스는 로드되지 않습니다. 동일한 파일을 사용하면 동시에 로드됩니다.
大家讲道理2017-04-18 10:54:20
AAA 클래스는 다른 곳에서는 새로운 것이 아니며 그에 따라 정적 필드를 가져오거나 설정하지도 않고 정적 메서드를 호출하지도 않습니다.
그래서 자동으로 초기화되지 않습니다.