最终变量。我已经阅读了本网站上可以找到的所有内容以及其他内容,我几乎了解它们,但我仍然有点困惑。
所以,我知道为什么我们将变量声明为final的官方答案:它锁定变量并阻止它被重新初始化。我的问题是这些:
如果无法重新初始化,它的价值仍然会改变吗?例如:
final int a = 1;
a = a + 1;
这种代码是否仍然可以使用,或者" final int a"永久锁定值为1?
如果上述int a
的值即使在宣布为最终版之后仍然可以更改,那么最终的结果是什么?
我猜问题2是我最大的问题。我一直看到关于它如何锁定变量的所有这些解释,有些人甚至说他们将大部分变量都称为最终变量,但这样做的动机对我来说没有意义。
答案 0 :(得分:5)
final int a = 1;
a = a + 1;
不,此代码不会通过编译,因为它会尝试为最终变量分配新值。
但是,如果a
的类型是某个可变类的引用类型,则可以改变对象的状态。例如:
final StringBuidler a = new StringBuilder (20);
a.append ("foo");
变量的final
仅阻止您更改其值。如果最终变量引用可以修改其状态的对象,则final
不会阻止您修改该状态。
答案 1 :(得分:2)
如果您声明
final int a = 1;
然后以下会导致编译错误,因为您声明为final,但是您尝试将变量重新分配给它:
a = a + 1;
但是,如果您有一个名为MyInt的对象,那么:
class MyInt{
int myInt = 5;
public int getInt() {
return myInt;
}
public void setInt(int newInt) {
myInt = newInt;
}
}
然后你这样做了:
final MyInt bestIntEver = new MyInt();
你还可以打电话
bestIntEver.setInt(42);
因为对bestIntEver
的引用不会改变,但
bestIntEver = new MyInt();
会导致编译错误,因为您正在更改对您声明为final的变量的引用。
答案 2 :(得分:0)
final
表示a
的值不会发生变化。但是,根据类型,a
的值实际上可能是对象的地址(在问题中它只是int
所以值不是地址,只是1)。锁定地址a
保持不会锁定对象。将对象设计为immutable将。
最喜欢的比喻就是一个公文包里面有一个1。一个不变的设计将锁定公文包,使人们无法进入并改变1. final
会将手铐铐到你的手腕上,这样人们就不会给你一个带有其他东西的新公文包。如果你想确保1你的任何事情都不会发生,你需要两者。
但这只是对象。
如果你是primitive(如int
),则没有公文包。你没有握住它的句柄(地址)。你手里拿着1只。
如果您是final
原语,则1已融合到您的手中。你不能放手。你无法接受其他任何事情。
对象或原语,final
的含义是相同的。无论你持有什么,地址或价值,你都要坚持到你死去。
如果上述int a的值即使在声明为final后仍然可以改变,那么最终的意义是什么?
它不能。
......他们宣称他们的大部分变数都是最终的,但这样做的动机对我来说没有意义。
当标识符被声明为final
时,将标识符称为变量实际上只是一个常见的坏习惯。如果它是最终的,它不是变量。它没有改变。这是一个常数。
创建常量有一些动机。语义正确性是一个。 是一个常量(3.14159 ......),所以改变它的值是没有意义的。另一个动机是防止导致错误的错误。变量经常被重用,因此分配了新的值。保护常量免受意外更改。你越能防止坏代码越好。