微醺,到底static还是static final才会有ConstantValue

兄弟们,今天就不多比比了,直接上菜 ,公众号阅读有惊喜!!!

作为Java开发的同学们,经常会见到如下代码

  
public class ClassTest {
    public final int fValue = 3;
    public static final int sfValue = 3;
}

这段源码文件就定义了两个变量,一个为static,一个为static final。这两个变量是啥意思我就不多说了吧,假设你不知道,我严重怀疑你在故意你在跟我开玩笑!
image

玩归玩,闹归闹,别拿Java开玩笑,这两个变量在源码层次上很容易理解,但是static和final会对Class文件产生什么影响呢?

透过文章标题可以清楚,这两个修饰符关联Class文件中ConstantValue属性的生成,ConstantValue只作用于字段表。

ConstantValue从字面上看是常量,或许此时很多不熟悉Class文件的读者朋友们直接通过你们错误的直觉给出了我答案,只要被final修饰的字段就会生成ConstantValue。

现实是残酷的,往往事与愿违,你要做的只不过是Java虐你千百遍,你要待它如初恋!!! 这样你才有可能抱得美人归。

其实细心的读者朋友们肯定已经通过标题发现,只有static或者static final才可能生成ConstantValue,到这里我们已经断定如果要生成ConstantValue必须要有static修饰(Class文件层面上字段表的标志上必须要ACC_STATIC)。

那么final到底对ConstantValue的生成有啥影响呢??

Java虚拟机规范规定了只要被static修饰的变量就会生成ConstantValue属性,只不过javac编译器在实现时加入了final的限制。也就是说javac编译器只会为被static final修饰的字段生成ConstantValue属性。

那么是不是只要被static final修饰的字段就会生成ConstantValue,只要你敢说是,那么Java就立马打你的脸,上(看)正(下)菜(图)!!!

WX20210116-110949@2x.png

attribute_name_index和attribute_length就不讲了,不明白的可以订阅一下我的JVM系列文章!!!

constantvalue_index是在Class文件常量池的索引,那么这个索引所在的位置是个字面量,由于在Class文件常量池中只有基本类型和和字符串相对应的字面量,因此ConstantValue只支持为基本类型和String生成,如果你非要Java为其他类型生成,说实在有点强人所难。

作为一个一直梦想拥有有趣灵魂的我,怎么可能只带大家干饭呢,再给大家上点饭后水果!!!!

巴拉巴拉讲了一大堆,那么ConstantValue属性生成了到底有啥子用?

这就牵扯到虚拟机对变量的初始化,对于非static变量初始化会在实例构造器方法中进行,但是对于static修饰的类变量,则可以选择在类构造器中或者使用ConstantValue属性进行初始化(这个主要取决于各类编译器的实现)

本期的ConstantValue属性就介绍到这,我们下期再见!!!

我是shysh95,希望可以和你专注技术的路上并肩作战,长按或者扫码关注微信公众号,更多精彩文章!!!

qrcode_for_gh_1706f00849c9_344.jpg

你可能感兴趣的:(javajvm)