使用此关键字为最终实例变量赋值

时间:2014-11-07 18:49:22

标签: java object final

我想了解最终变量用法中缺少的内容。我尝试用谷歌搜索这个奇怪的(至少对我来说)行为,并且很想知道幕后发生了什么。

  

Java规范说:   变量可以声明为final。 最终变量只能分配给 。声明变量> final可以作为有用的文档,它的价值不会改变,可以帮助避免编程>错误。

     

如果指定了最终变量,那么这是一个编译时错误,除非它是明确未分配的(§16)>在转让之前。

     

空白决赛是一个最终变量,其声明缺少初始值。


现在考虑以下代码:

public class Sample {
    private final int a;
    private final Object object1; // compile error that object1 is not initialized
    private final Object object2 = null;

    public Sample(int value) {
        System.out.println(this.a);
        a = value;
        System.out.println(this.a);
        object2 = new Object(); // Compile error that it shouldn't change
    }
}

以下是我的观察:

  • 在第2行public final int a中,JVM会将默认值0分配给
  • 这就是为什么构造函数中的第一个print语句打印值“0”
  • 然后我们尝试将默认值修改为传递给构造函数的“value”(a=value)
  • 它允许更改值,然后从下一个赋值中,编译器将给出错误。
  • 在对象private final Object object1的情况下,它给出了编译时错误,即object1未初始化。虽然默认情况下JVM默认为实例成员分配“null”值。
  • 一旦为对象分配了值private final Object object2=null,那么它的工作方式就像预期的那样。

现在有人可以使用默认分配原语对象来回答为什么编译器的行为方式不同使用 final 关键字?

如果您觉得这个愚蠢的问题很抱歉,我请求您指出我可以得到答案的来源。


由于
沙拉斯

1 个答案:

答案 0 :(得分:3)

  

在第2行的public final int中,JVM会将默认值0分配给

这就是JVM的功能。这是编译器的作用 - 它不是源代码中的赋值。它只是变量在赋值之前的值。

JLS并未说明您无法在构造函数中观察到最终变量的值。它说你必须分配一个最终变量一次。这就是a的情况 - 它唯一的赋值在构造函数中,所以没关系。

这里的基元和类之间没有区别 - 如果显式在字段声明中将值0指定给a,则在发生时会看到相同的错误您尝试在构造函数中分配a