Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
563 views
in Technique[技术] by (71.8m points)

Static 标识的字段或者是代码块,真的是在类加载的时候初始化的吗?

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版》中找到一些线索,如下图:
图片描述

所以,照这么说,是在第一次主动访问该类的时候执行?小弟好生迷惑啊....大家快说说你们的观点


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

真心感谢楼上热心网友们的解答!

验证

AAA 类确实没有被加载,只有 Main 类被加载(题干截图:初始化条件第四条,主类被 jvm 自动加载)

java -XX:+TraceClassLoading Main

结论

类中 静态字段|代码块 真的是在类加载的时候被初始化或者是执行的!

延伸

怎么知道类有没有被 jvm 所加载?

这也是我一直纠结的问题,一开始以为只要执行了 javac 命令,类就被 jvm 加载了,其实不然,该命令只是将 .java 文件转化成 jvm 能读懂的 .class 文件而已。

那么到底怎么知道类有没有被 jvm 所加载?
据 《深入理解Java虚拟机:JVM高级特性与最佳实践 第2版》 和广大网友的热心解答可知,并没有明确的时机规定了啥时候会被加载!

但是!jvm 明确规定了类被初始化的时机-就是题干上截图部分那四种!而类的加载是优先于类初始化的,所以这里,我们暂且可以认为这几种情况就是触发类加载的条件。

小弟愚昧,总结不妥之处,还麻烦大家指正!感谢


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...