常量有任何正式定义吗?

10

Java规范是否定义了常量原则,还是只留下了推荐角色?

如果在规范中定义了,它的定义是什么?

具体来说,以下任何或所有示例是否被认为是常量?如果某些或全部确实是,根据规范或任何其他官方推荐,它们是否被认为是这样的?

public static final int ONE = 1;
public static final double TWO = 2.0d;
public static final String THREE = "three";
public static final ImmutableList<Integer> ONE_TWO_THREE = ImmutableList.of(1, 2, 3);
public static final Logger logger = LogManager.getLogManager().getLogger(ThisClass.class);

14
@SharonBenAsher:我不同意这是“完全重写”。问题的实质并没有改变:在Java中,static final变量是否总是被视为“常量”? - Nicol Bolas
10
@SharonBenAsher:这个问题的含义并没有太多歧义。它非常明确地说,“所有static final字段是否都是常量?或者规范允许我决定哪些字段是常量?”“值”或“业务”的问题只是一个例子。 - Nicol Bolas
16
不,原始问题并不是关于命名规范的。原始问题与现在的问题完全相同。它从未涉及命名规范。 - Servy
7
@SharonBenAsher 确实有相当数量的人误解了问题。由于问题表述不清,无法有效地传达所要询问的内容。现已进行澄清以解决这个问题。 - Servy
17
请前往 meta 讨论区,讨论关于我的问题被标记为“基于意见”的情况,在第五个投票之前我进行了编辑。 - Olivier Grégoire
显示剩余18条评论
1个回答

16

Java语言中有两种使用常量的方式。其中一种是常量表达式,这在规范中有定义。请参见第15.28章 常量表达式

一个常量表达式是指由以下内容组成的,不会突然停止并表示原始类型或字符串值的表达式:
  • 原始类型字面量和字符串字面量(§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),其中包含的表达式是常量表达式。
  • 简单名称(§6.5.6.1)指向常量变量(§4.12.4)。
  • 限定名称(§6.5.6.2)形式为 TypeName.Identifier,指向常量变量(§4.12.4)。
如果您点击常量变量的链接,您会发现:

一个空白的final是一个没有初始化器声明的final变量。

常量变量是一个基本类型或类型Stringfinal变量,它被一个常量表达式(§15.28)初始化。无论变量是否为常量变量,都可能影响类初始化(§12.4.1)、二进制兼容性(§13.1、§13.4.9)和确定赋值(§16(确定赋值))。

因此,不需要使用static。Java语言只关心变量是否为final并在其声明时用常量表达式进行初始化。

还有枚举常量,它们是枚举实例。


其他用途是开发人员用来指称某些不会改变的东西(无论是非常数final变量还是其他东西���。在将它们与上述常量一起使用时要小心。

话虽如此,你的示例包含变量,根据上述规范以及那些不被认为是常量的变量,这些变量被视为常量。前三个变量是final和原始类型或String类型,因此是常量变量

public static final int ONE = 1;
public static final double TWO = 2.0d;
public static final String THREE = "three";

尽管被声明为 "final",但最后两个变量并不被视为常量变量,因为它们既不是原始类型,也不是 "String" 类型。
public static final ImmutableList<Integer> ONE_TWO_THREE = ImmutableList.of(1, 2, 3);
public static final Logger logger = LogManager.getLogManager().getLogger(ThisClass.class);

4
因此,查看您贴子版本2中的原始示例,无论是public static final ImmutableList<Integer> ONE_TWO_THREE还是private static final Logger logger应被视为常量变量,因为它们既不是基本类型的变量也不是String类型的变量。 - altocumulus
1
@altocumulus 这确实是我阅读时想要强调的重要部分之一。虽然没有明确写出,但感谢你做到了这一点。 - Olivier Grégoire
@OlivierGrégoire 由于这是一个社区维基帖子,你可以自由地根据你的需要进行编辑。个人而言,我更喜欢在你的问题中至少包含第2版的示例,并将我的评论中的信息合并到答案中。 - altocumulus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接