为什么实例变量是最终的?

我读了关于不可变对象的这个问题 ,并留下了关于不可变对象和最终字段的问题:

为什么我们需要在不可变类中的实例变量为final?

例如,考虑这个不可变类:

public final class Immutable { private final int someVal; public Immutable(int someVal) { this.someVal= someVal; } public int getVal() { return val; } } 

如果在上面的代码中没有set方法,并且实例变量只在构造函数中设置,为什么要求将实例变量声明为final?

没有要求使变量成为final变量。 但是,如果您明确打算永远不要更改变量,那么通常最好将其变为final变量,因为这不仅强制执行对打字错误或其他错误的不变量,而且还声明它不可变的意图,例如,其他程序员或你自己。

如果变量是public ,那么您将严格要求使其成为final变量,以确保接口代码不会更改其值。

请注意,您链接的问题并不直接相关,因为它讨论的是final ,而不是变量。 使类final意味着它不能inheritance,而不是它是不可变的。 然而,在制作不可变对象时,肯定有一个案例需要注意该问题的内容及其答案; 但它仍然是一个单独的问题。

通过将所有类的字段标记为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++; } } 

如果字段不是final很容易无意中添加一个修改对象状态的方法。 通过将它们标记为final ,这个其他程序员在尝试修改字段时会收到编译错误,并且必须问自己为什么这个字段是final ,并且他的修改是否违反了这个类的合同。

有人可能会说Javadoc应该被用来记录所说的类是不可变的,但坦率地说,不是每个人都读Javadoc。 在我看来,让代码说话本身更好。

在不可变类中,您无法更改其属性/字段的状态。 通常,它是通过不向类的客户端代码提供setter方法来完成的。

static final关键字的组合用于使变量保持不变。 声明为final的变量一旦初始化就永远不会改变它的值。

因为在不可变类中你永远不需要改变属性/字段状态,所以最好让它成为最终状态。