Java常量的编译时值绑定

时间:2014-08-18 19:53:20

标签: java static constants

根据最后一个注释here

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

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

所以 - 按照上面的规范,如果我将PI的值从3.14更改为class A中的3.0,我必须重新编译class B以获得效果class B中的变化。

这里的Q是 - 上面的规范中“常数”的定义到底是什么? 它是final关键字吗?在这种情况下,任何static字段成员是否“限定”为常量? 这里的非静态字段成员将脱离上下文 - 它们的值在运行时(?)分配

TIA。

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

编辑:

这里的Q是:编译器决定在编译时绑定值的原因。 static关键字是否完成了这项工作。或者还有其他什么东西。

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

参考下面的快速回答,不断投票:

同一页上的一行:

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

1。)“... 用于定义常量....”:还有什么定义常量。

2。)“... 结合最终修饰符”:final是编译时限制值所必需的 - 我怀疑它是什么。

4 个答案:

答案 0 :(得分:3)

您甚至没有看过您提到的链接?

  

常量

     

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

答案 1 :(得分:3)

JLS $ 15.28. Constant Expressions

编译时常量表达式是表示基本类型值的表达式或不突然完成的字符串,仅使用以下内容组成:

  • String类型的原始类型和文字的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)

  • 转换为基本类型并转换为String类型(第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节)。

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

  • TypeName形式的限定名称(第6.5.6.2节)。引用常量变量的标识符(§4.12.4)。

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

  • 编译时常量表达式始终被视为FP-strict(第15.4节),即使它出现在非常量表达式不被认为是FP严格的上下文中。

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

答案 2 :(得分:0)

  

上述规范中“常数”的定义究竟是什么?

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

  

是最终关键字吗?

这是必需的。

  

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

不,将其设为静态是一种优化,但不是必需的。

  

这里的非静态字段成员将脱离上下文 - 它们的值在运行时分配(?)

不一定。

答案 3 :(得分:0)

public

使变量可以从任何地方到达。

static

仅实例化变量一次,并允许您在每个变量调用上使用相同的地址。

final

使变量本身不可更改。

这三个都使你的变量变为常量,因为它不能被改变,它只实例化一次..