Java 使用此关键字为最终实例变量赋值
我想了解在使用final变量时缺少了什么。我在谷歌上搜索了很多关于这种奇怪(至少对我来说)行为的信息,很想知道幕后发生了什么 Java规范说: 变量可以声明为final最终变量只能分配一次。声明变量>final可以作为有用的文档,它的值不会改变,并且可以帮助避免编程>错误 如果将最终变量赋值给,则为编译时错误,除非它在赋值之前明确未赋值(§16)> 空final是其声明缺少初始值设定项的final变量。Java 使用此关键字为最终实例变量赋值,java,object,final,Java,Object,Final,我想了解在使用final变量时缺少了什么。我在谷歌上搜索了很多关于这种奇怪(至少对我来说)行为的信息,很想知道幕后发生了什么 Java规范说: 变量可以声明为final最终变量只能分配一次。声明变量>final可以作为有用的文档,它的值不会改变,并且可以帮助避免编程>错误 如果将最终变量赋值给,则为编译时错误,除非它在赋值之前明确未赋值(§16)> 空final是其声明缺少初始值设定项的final变量。 现在考虑下面的代码: public class Sample { private
现在考虑下面的代码:
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行
中,JVM将为a分配一个默认值0public final int a
- 这就是构造函数中的第一个print语句打印值“0”的原因
- 然后我们尝试将默认值修改为传递给构造函数的“value”
(a=value)
- 它允许更改值,然后从下一个赋值开始,编译器将给出一个错误
- 而在对象
的情况下,它会给出一个编译时错误,即object1未初始化。尽管默认情况下JVM会为实例成员默认分配一个“null”值私有最终对象object1
- 一旦为该对象分配了一个值
,那么它的工作原理与预期基本相同private final object object2=null
谢谢
沙拉斯 在第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提供的信息。