为什么最终变量并不总是常量表达式?

在下面的代码中:

final int a;
a=2;
byte b=a;   // error: possible loss of precision

为什么我会收到此错误?最终变量编译时不是常量表达式,因此在赋值期间隐式缩小到字节吗?a

换句话说,上面的代码并不等同于:

final int a=2;
byte b=a;

答案 1

来自 JLS

空白 final 是其声明缺少初始值设定项的变量。final

常量变量是使用常量表达式 (§15.28) 初始化的基元类型或类型的变量。finalString

您的变量

final int a;

空白的最终变量。它缺少初始值设定项。第二段不适用于它,因为它在声明时未初始化。因此,它不是一个常量表达式。

这也适用于字段。


答案 2

编译器不是那么聪明。

我们可以看出,该值将始终为 2。但是,如果我们有这样的东西呢?

class ABC{
    final int a;

    public ABC(){
       if(Math.random() < .5){
          a = 2;
       }
       else{
          a = 12345;
       }

       byte b = a;
    }
}

编译器不够智能,无法区分这两种情况,因此它会给你一个错误。


推荐