常量有正式定义吗?

Is there any formal definition of constants?

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);

常量在Java语言中有两种用法。有 常量表达式 并且它们在规范中定义。参见 Chapter 15.28 Constant Expressions

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)
  • Casts to primitive types and casts to type String (§15.16)
  • The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)
  • The multiplicative operators *, /, and % (§15.17)
  • The additive operators + and - (§15.18)
  • The shift operators <<, >>, and >>> (§15.19)
  • The relational operators <, <=, >, and >= (but not instanceof) (§15.20)
  • The equality operators == and != (§15.21)
  • The bitwise and logical operators &, ^, and | (§15.22)
  • The conditional-and operator && and the conditional-or operator || (§15.23, §15.24)
  • The ternary conditional operator ? : (§15.25)
  • Parenthesized expressions (§15.8.5) whose contained expression is a constant expression.
  • Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
  • Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).

如果您按照 constant variables 的 link,您会发现

A blank final is a final variable whose declaration lacks an initializer.

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28). Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9), and definite assignment (§16 (Definite Assignment)).

所以 static 不是必需的。 Java 语言只关心变量是 final 并在声明时用常量表达式初始化。

还有 enum constants 枚举实例。


其他用途是开发人员用来指代不会改变的东西(无论是非常量 final 变量还是其他东西)。小心如何将它们与上面的 常量 结合使用。


也就是说,您的示例包含根据上述规范被视为常量的变量,以及那些不是常量的变量。前三个变量是 final 并且是原始类型或 String 类型,因此是 常量变量 :

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

虽然被声明为final,但最后两个变量被认为是常量变量,因为它们既不是原始类型也不是[=12=类型]:

public static final ImmutableList<Integer> ONE_TWO_THREE = ImmutableList.of(1, 2, 3);
public static final Logger logger = LogManager.getLogManager().getLogger(ThisClass.class);