我读到了这个关于不可变对象的问题,留下了一个关于不可变对象和final字段的问题:
为什么我们需要不可变类中的实例变量成为最终变量?
例如,考虑这个不可变类:
public final class Immutable
{
private final int someVal;
public Immutable(int someVal)
{
this.someVal= someVal;
}
public int getVal() {
return val;
}
}
如果在上面的代码中没有设置方法,并且实例变量只在构造函数中设置,那么为什么需要将实例变量声明为final?
在不可变类中,你不能改变它的属性/字段的状态。通常,这是通过不向类的客户端代码提供setter方法来实现的。
而<code>static final<code>关键字的组合用于使变量变为常量。声明为final的变量一旦初始化,就永远不能更改其值。
因为在不可变类中,你永远不需要改变属性/字段的状态,所以最好把它变成final。
通过将类的所有字段标记为最终
字段,您可以清楚地表明您希望类是不可变的。
假设您有以下类:
public class Immutable {
private int value;
public Immutable (int value) {
this.value = value;
}
public int getValue () {
return value;
}
}
没有 setter 方法,因此可以很容易地假设此类是不可变的。现在就是这样。但最终你的类将被其他程序员修改,这个程序员可能会向你的类中添加一些方法:
public class Immutable {
private int value;
public Immutable (int value) {
this.value = value;
}
public int getValue () {
return value;
}
public void doSomething () {
value++;
}
}
如果字段不是最终的,则很容易无意中添加一个修改对象状态的方法
。通过将它们标记为最终
,其他程序员在尝试修改字段时将收到编译错误,并且将不得不问自己为什么这个字段是最终
的,并且他的修改是否破坏了该类的契约。
有人可能会争辩说Javadoc应该用来记录所说的类是不可变的,但坦率地说,并不是每个人都阅读Javadoc。在我看来,让代码自己说话更好。
不要求将变量< code >设为final。然而,当你确实明确地打算永远不改变变量时,通常把它变成< code>final是一个好的做法,因为这不仅加强了不变量对打字错误或其他错误的抵抗力,而且声明了它对其他程序员或你自己来说是不可变的。
如果变量是< code>public,那么您必须将它设为< code>final,以确保接口代码不能更改它的值。
但是,请注意,您链接的问题并不直接相关,因为它讨论的是Final
的类,而不是变量。使类Final
意味着它不能从继承,而不是它是不可变的。然而,在创建不可变对象时,当然有理由注意该问题的内容及其答案;但这仍然是一个单独的问题。
问题内容: 我读了这个问题不可变对象,并留下了关于不可变对象,并最终场一个问题: 为什么我们需要不可变类中的实例变量为最终变量? 例如,考虑以下不可变的类: 如果在上面的代码中没有set方法,而实例变量仅在构造函数中设置,为什么要求将实例变量声明为final? 问题答案: 有没有 要求 这样做的变量。但是,当您确实明确打算永远不更改变量时,通常这样做是一种好习惯,因为这不仅可以使变量避免错别字或其
问题内容: 这个问题已经在这里有了答案 : 为什么在匿名类中只能访问最终变量? (15个答案) 为什么实例变量“忽略Lambda表达式中使用的变量必须是最终变量或实际上是最终变量”警告[重复] (2个答案) Lambdas:局部变量不需要最终变量,实例变量不需要 (10个答案) 2年前关闭。 当我编写此代码时,我收到一个编译时错误,该错误是: “ lambda中的变量必须是final或有效的fin
问题内容: 将实例变量作为最终变量有什么意义? 那么将该变量设置为静态最终变量会更好吗? 原因是如果任何对象都不能更改它,那么它与类(静态)变量相同,对吗? 问题答案: 不。 表示该类的所有实例都相同。 表示在初始分配后无法分配。因此,两个实例的非静态最终变量的值可能不同。 您可能有很多原因想使变量为final;最好的方法之一就是清晰度。如果我读了一个方法并且注意到foo是最终的,那么我不必担心它
问题内容: 例如,如果我有一个变量,并且在主线程中声明了一个runnable,并且想将x传递给该runnable的方法,则必须对其进行声明。为什么? 问题答案: 因为如果能够更改它们,可能会导致很多问题,请考虑以下事项: 这是一个粗略的示例,但您可以看到可能发生许多无法解释的错误。这就是变量必须为最终变量的原因。这是解决上述问题的简单方法: 如果您需要更完整的说明,则有点像同步。Java希望防止您
问题内容: 如果省略,则会看到错误“ 无法在用其他方法定义的内部类中引用非最终变量jtfContent ”。 为什么匿名内部类必须要求外部类实例变量为final才能访问它? 问题答案: 首先,让我们放松一下,请放下那把枪。 好。现在,语言坚持的原因是它作弊是为了让你的内部类函数可以访问他们渴望的局部变量。运行时复制本地执行上下文(以及其他适当的内容),因此它坚持要求你进行所有操作,final以使事
问题内容: 6年前关闭。 有关匿名类的文档说明 匿名类无法在其封闭范围内访问未声明为final或有效地为final的局部变量。 我不明白变数为“有效的最终”是什么意思。有人可以提供一个示例来帮助我理解这意味着什么吗? 问题答案: 有效地最终意味着它在获得初始值之后永远不会改变。 一个简单的例子: 在这里,并没有声明为final,但是由于它从未更改,因此实际上被认为是 final 。 从Java 8