Java常量的编译时值绑定

Java常量的编译时值绑定,java,static,constants,Java,Static,Constants,根据最后一点说明: “如果原语类型或字符串被定义为常量,并且在编译时已知该值,编译器将用其值替换代码中任何地方的常量名称。这称为编译时常量。如果外部世界中常量的值发生变化(例如,如果法律规定pi实际上应为3.975),则需要重新编译使用此常量的所有类以获取当前值。“ 假设我在类a中定义了一个公共常量PI(public static final double PI=3.14),并且 在B类中使用该常数PI 因此,根据上述规范,如果我将PI的值从3.14更改为class A中的3.0,我必须重新编译

根据最后一点说明:

“如果原语类型或字符串被定义为常量,并且在编译时已知该值,编译器将用其值替换代码中任何地方的常量名称。这称为编译时常量。如果外部世界中常量的值发生变化(例如,如果法律规定pi实际上应为3.975),则需要重新编译使用此常量的所有类以获取当前值。“

假设我在
类a
中定义了一个公共常量
PI
public static final double PI=3.14
),并且 在
B类中使用该常数
PI

因此,根据上述规范,如果我将
PI
的值从3.14更改为
class A
中的3.0,我必须重新编译
class B
,以获得
class B
中更改的效果

这里的问题是——在上述规范中,“常量”的定义到底是什么? 它是
最终的
关键字吗?在此上下文中,是否有任何
静态
字段成员“限定”为常量? 这里的非静态字段成员将与上下文无关——它们的值是在运行时分配的(?)

蒂亚

//===========================

编辑:

这里的问题是:是什么使编译器决定在编译时绑定值。
static
关键字是否独自完成此任务。或者还有什么别的原因

//=======================

下面是一个不断获得投票支持的快速答案:

同一页上的行:

静态修饰符与最终修饰符一起也用于定义常量。最终修饰符表示此字段的值不能更改

1.“…也是用来定义常数的:”:还有什么定义常数


2.“…final修饰符结合使用”:是在编译时绑定值所必需的,我对此表示怀疑

你甚至没有阅读你提到的链接

常数

static
修饰符与
final
修饰符结合使用,也用于定义常量。
final
修饰符表示此字段的值不能更改

上述规范中“常量”的定义是什么

它必须是最终的,并且编译器可以在不使用方法的情况下使用表达式进行计算

这是最后一个关键词吗

这是必需的

在此上下文中,是否有任何静态字段成员“限定”为常量

不,使其静止是一种优化,但不是必需的

这里的非静态字段成员将与上下文无关——它们的值是在运行时分配的(?)

不一定。

编译时常量表达式是一个表示原语类型的值或字符串的表达式,该值或字符串不会突然完成,并且仅使用以下内容组成:

  • 基本类型的文字和字符串类型的文字(§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)

  • 条件and运算符&&和条件or运算符| |(§15.23,§15.24)

  • 三元条件运算符?:(§15.25)

  • 括号表达式(§15.8.5),其包含的表达式为常量表达式

  • 引用常量变量的简单名称(§6.5.6.1)

  • 格式TypeName的限定名(§6.5.6.2)。指常量变量的标识符(§4.12.4)

  • String类型的编译时常量表达式总是“interned”,以便使用String.intern方法共享唯一实例

  • 编译时常量表达式始终被视为FP-strict(§15.4),即使它发生在非常量表达式不被视为FP-strict的上下文中

编译时常量表达式用于switch语句(§14.11)中的case标签,对于赋值转换(§5.2)和类或接口的初始化(§12.4.2)具有特殊意义。它们还可以控制while、do或for语句正常完成的能力(§14.21),以及条件运算符的类型:使用数字操作数

public
使变量可以从任何地方访问

static
仅实例化变量1次,并允许您在每次变量调用时使用相同的地址

final
使变量本身不可更改


这三个变量都会使变量保持不变,因为它不能更改,并且只实例化一次。

我建议使用+1,这不是问题本身,而是因为TIL更改
static final
类成员的值会破坏二进制兼容性!这个-很好。然而,这种编译时值绑定发生在哪里——静态上下文中的常量值发生在哪里?当我问这个问题的时候,我只想到了字段成员声明——但是现在变得越来越大了。无论常量值出现在哪里,周期都会变长。