3 回答
TA贡献1712条经验 获得超3个赞
编译时间常数必须为:
宣布最终
原始或字符串
在声明中初始化
用常量表达式初始化
所以private final int x = getX();
不是恒定的。
第二个问题private int y = 10;
不是恒定的(在这种情况下是非最终的),因此优化器无法确定该值将来不会更改。因此,它无法将其优化为恒定值。答案是:不,它与编译时间常数的处理方式不同。
TA贡献2080条经验 获得超4个赞
该JLS使得之间的区别如下final变量和常量:
final 变数
可以声明一个变量final。甲final变量可以仅被分配给一次。如果将final变量赋值给它,则是编译时错误,除非在赋值之前绝对未赋值(第16节(确定赋值))。
一旦一个final变量被分配,它总是包含相同的值。如果final变量持有对对象的引用,则可以通过对对象的操作来更改对象的状态,但是变量将始终引用同一对象。这也适用于数组,因为数组是对象。如果final变量持有对数组的引用,则可以通过对数组的操作来更改数组的组件,但是变量将始终引用同一数组。
一个空白的final是一个final变量,其声明中缺少一个初始化。
常数
甲常量变量是final原始类型或类型的变量 String,其与一个常量表达式(初始化§15.28)。
从这个定义中,我们可以看出一个常数必须是:
宣告 final
原始类型或类型 String
在其声明中初始化(不是空白final)
用常量表达式初始化
编译时常量呢?
该JLS不包含短语编译时间常数。但是,程序员经常将术语“ 编译时常量”和“ 常量常量”互换使用。
如果final变量不满足上述标准,则该final变量在技术上应称为变量。
TA贡献1779条经验 获得超6个赞
根据JLS,没有要求“常量”应该是静态的。
因此,“常量”可以是静态的也可以是非静态的(实例变量)。
但是JLS对变量成为“常量变量”(除了只是最终变量)施加了一些其他要求:
仅是字符串或原始
仅初始化为内联,因为它是最终的,并且不允许空白的最终
用“常量表达式” =“编译时常量表达式”初始化(请参见下面的JLS引用)
4.12.4。最终变量(JLS)
甲常量变量是原语类型的最终变量或输入与一个常量表达式初始化字符串(§15.28) 。
15.28。常数表达式
甲编译时间常量表达式是表示原始类型或String不突然完成,并且仅使用以下组成的一个值的表达式:
基本类型的文字和字符串类型的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)
强制转换为基本类型,强制转换为字符串(第15.16节)
一元运算符+,-,〜和!(但不是++或-)(§15.15.3,§15.15.4,§15.15.5,§15.15.6)
乘法运算符*,/和%(第15.17节)
加法运算符+和-(§15.18)
移位运算符<<,>>和>>>(第15.19节)
关系运算符<,<=,>和> =(但不包括instanceof)(第15.20节)
等号运算符==和!=(§15.21)
按位和逻辑运算符&,^和| (§15.22)
条件和运算符&&和条件或运算符|| (§15.23,§15.24)
三元条件运算符?:(§15.25)
带括号的表达式(第15.8.5节),其包含的表达式是一个常量表达式。
引用常量变量(第4.2.4节)的简单名称(第6.6.5.6.1节)。
TypeName形式的合格名称(第6.5.6.2节)。引用常量变量的标识符(第4.12.4节)。
添加回答
举报