45

在下面的代码中:

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

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

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

final int a=2;
byte b=a;
4

3 回答 3

51

来自JLS

空白finalfinal其声明缺少初始化程序的变量。

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

你的变量

final int a;

是一个空白final变量。它缺少初始化程序。第二段不适用于它,因为它没有在声明时初始化。因此,它不是一个常量表达式。

这也适用于字段。

于 2015-06-11T15:37:00.937 回答
43

编译器不是那么聪明。

我们可以说这个值永远是 2。但是如果我们有这样的东西呢?

class ABC{
    final int a;

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

       byte b = a;
    }
}

编译器不够聪明,无法区分这两种情况,所以它会给你一个错误。

于 2015-06-11T15:43:46.690 回答
2

由于最终变量可以延迟初始化,并且编译器无法确定 b 在 case 分支中有值。

于 2015-06-11T15:37:50.263 回答