为什么Java语言规范说表达式(n> 2)不是常量表达式?

在“ 定义分配的Java语言规范”一章中, 例16-2说明了这一点

Java编译器必须为代码生成编译时错误:

{ int k; int n = 5; if (n > 2) k = 3; System.out.println(k); /* k is not "definitely assigned" before this statement */ } 

即使n的值在编译时是已知的,并且原则上可以在编译时知道对k的赋值将始终被执行(更恰当地,被评估)。 Java编译器必须按照本节中规定的规则运行。 规则只承认常量表达式; 在此示例中, 表达式n> 2不是§15.28中定义的常量表达式。

但是,如果我们看一下§15.28,就会说

关系运算符<,和> =

可以有助于持续表达。

表达式n > 2为常量表达式? 我们怎样才能确定这个?

它是这样说的,因为n不是一个常数表达式 。

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

  • […]
  • 引用常量变量的简单名称(第6.5.6.1节) (§4.12.4) 。

常量变量是基本类型的final变量或用常量表达式初始化的String类型(第15.28节)。

n不是final ,因此不是常数变量。 因此,它不是一个恒定的表达。 因此n < 2不是常数表达式。

你误读了规范的§15.28。 该部分列出了常量表达式中允许的语言元素。 如果表达式中没有任何内容,那么它不是常量表达式。 它并不意味着(因为你显然读它的意思)如果列表中的任何元素存在,那么表达式是常量。

从语言规范(强调添加):

常量表达式是表示基本类型的值的表达式或不突然完成的String使用以下内容组成:
…等

表达式n > 2不是常量表达式,因为n未声明为final ,因此n不是常量。 尽管它在代码中的那个值只能是5,但它不符合常量的语言定义。 (参见§4.12.4 ,由§15.28引用。)