我们可以看到sum.misc.Version里面的launcher_name字段的值就是“java”:
而根据R大的回答,我们可以找到java.lang.System类:
根据System类的注释我们可以知道,它是由虚拟机自动调用的。而其initializeSystemClass方法会调用sun.misc.Version.init()方法。
到此就真相大白了。
Java标准库在JVM启动过程中会调用sun.misc.Version的init()方法。所以sun.misc.Version会进行类加载的操作,而类加载的初始化阶段时,会对静态常量字段进行真正的赋值操作,但是由于sun.misc.Version的launcher_name字段是final修饰的,所以引用的字符串“java”在准备阶段就被intern到了字符串常量池里面了。
可以在心里在默默的复习一下类加载的过程:加载、验证、准备、解析和初始化这五个阶段哦。
另外书中给出的示例代码也有一定的局限性,R大是这样说的:
其实这事情很简单:首先,这个行为必然是要针对某个具体的JDK/JRE实现来讨论的,因为Java语言规范/JVM规范/Java SE标准库的JavaDoc(也是Java SE平台规范的一部分)都没有、也不会强制指定哪个类里一定要引用“java”这个字符串常量,而且它必须是第一个使得“java”被intern的类 --- 规定这个也太无聊了。
比如这个示例我在JDK8u212-b03上跑出来,就是两个true:
在这个版本里面,sun.misc.Version的launcher_name变成了“openjdk”:
那么根据我们之前的猜测,把程序成下面这样的,效果就是一样的了:
万变不离其宗,现在你知道为什么这里用openjdk返回也是false了吧。
知其然,还要知其所以然。
R大与周志明之间的“爱恨情仇”
R大是谁?
我先上一张《深入理解java虚拟机(第二版)》背面的一张图吧,R大给这本书写过推荐语:
莫枢(RednaxelaFx)Oracle HotSpot VM编译器团队工程师。(现在他已经不在Oracle了。据网上公开资料,R大是前阿里巴巴技术专家,前Oracle JVM核心开发,前Azul核心开发,现就职于Databricks)
再看一下他的知乎主页:https://www.zhihu.com/people/rednaxelafx/answers
你去知乎上只搜RednaxelaFX(甚至直接用搜索引擎搜索),就能搜到很多结果,我随便截取一个片段。
在【有哪些顶级水平的中国程序员?】这个话题下,有一个回答只是@一下R大的ID,没有多说一个字,就获得了258个赞,评论中也满是赞美的语言,干货多,就是他的特点:
他与《深入理解Java虚拟机》的作者周志明大大,在2010年到2011年间,在iteye上已经有过多次深度交流,比如下面的吐槽:
比如下面的调侃:
玩归玩,闹归闹,周志明也直言阅读了R大的很多文章,受益良多:
并且在书里的致谢章节专门谢谢了R大:
说这么多,我想要表达的观点其实就是一个:
R大是一个宝藏啊,他乐于分享和交流,凭借一己之力推动了国内jvm的学习和研究,如果你想要了解虚拟机、编译原理和编程语言方面的相关知识,他是一个你绕不过的人。他值得被更多的程序员知道。
如果你之前不知道,但看了我这篇文章后知道了他,我的目的就达到了。
他在知乎上认认真真码字,用心的对待每一个回答,他是一个"码"宗强者,恐怖如斯,但是从他的各种回答、博客文章中,你可以感觉到谦逊、细致、系统、耐心、专业、严谨.....就像一个评论说的:
在技术圈日益浮躁的今天,感觉他就是主席所说的那种:一个纯粹的人,一个有道德的人,一个脱离了低级趣味的人,一个有益于人民的人。
我们做程序的,要向他学习,向他致敬。
最后再附上一个R大的资料合集链接吧,全是宝藏,待你去发掘:
https://zhuanlan.zhihu.com/p/25042028
最后说一句
才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言给我指出来,我对其加以修改。
如果你觉得文章还不错,你的转发、分享、点赞、留言就是对我最大的鼓励。
感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。
以上。
欢迎关注公众号【why技术】,坚持输出原创。分享技术、品味生活,愿你我共同进步。