Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用此关键字为最终实例变量赋值_Java_Object_Final - Fatal编程技术网

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

Java 使用此关键字为最终实例变量赋值,java,object,final,Java,Object,Final,我想了解在使用final变量时缺少了什么。我在谷歌上搜索了很多关于这种奇怪(至少对我来说)行为的信息,很想知道幕后发生了什么 Java规范说: 变量可以声明为final最终变量只能分配一次。声明变量>final可以作为有用的文档,它的值不会改变,并且可以帮助避免编程>错误 如果将最终变量赋值给,则为编译时错误,除非它在赋值之前明确未赋值(§16)> 空final是其声明缺少初始值设定项的final变量。 现在考虑下面的代码: public class Sample { private

我想了解在使用final变量时缺少了什么。我在谷歌上搜索了很多关于这种奇怪(至少对我来说)行为的信息,很想知道幕后发生了什么

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

如果将最终变量赋值给,则为编译时错误,除非它在赋值之前明确未赋值(§16)>

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


现在考虑下面的代码:

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将为a分配一个默认值0
  • 这就是构造函数中的第一个print语句打印值“0”的原因
  • 然后我们尝试将默认值修改为传递给构造函数的“value”
    (a=value)
  • 它允许更改值,然后从下一个赋值开始,编译器将给出一个错误
  • 而在对象
    私有最终对象object1
    的情况下,它会给出一个编译时错误,即object1未初始化。尽管默认情况下JVM会为实例成员默认分配一个“null”值
  • 一旦为该对象分配了一个值
    private final object object2=null
    ,那么它的工作原理与预期基本相同
现在,有人能回答:为什么编译器在使用final关键字时会对原语和对象执行不同的默认赋值

如果你觉得这是一个愚蠢的问题,我很抱歉,但我要求你指出一个我可以得到答案的来源


谢谢
沙拉斯

在第2行public final int a中,JVM将为a分配一个默认值0

JVM就是这样做的。这不是编译器所做的-它不是源代码中的赋值。它只是变量在赋值之前的值

JLS并没有说您不能观察构造函数中最终变量的值的变化。它说你必须给最后一个变量赋值一次。这正是
a
的情况-对它的唯一赋值是在构造函数中,所以这很好


原语和类之间没有区别-如果您在字段声明中显式地将
0
的值赋值给
a
,那么当您尝试在构造函数中赋值给
a
时,您将看到相同的错误。

谢谢Jon的回答,而我还有几个问题。1.我觉得编译器也知道jvm为变量分配了一个默认值,否则它会抛出一个错误,即对象没有按照第3行中的说明初始化。2.我说过关于原语的区别是因为只有对于原语,编译器不会抛出表示最终变量未初始化的错误。如果我遗漏了什么,很抱歉。@SharathBhaskara:1。不,不会-您在
object1
中遇到的错误是因为它从未赋值。2.绝对不是-看看你的错误,它说
object2
从未初始化过,这不是一个基本类型。。。将其更改为基元类型根本不会改变错误。谢谢Jon提供的信息。