为什么实例变量是最终的?
我读了关于不可变对象的这个问题 ,并留下了关于不可变对象和最终字段的问题:
为什么我们需要在不可变类中的实例变量为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的变量一旦初始化就永远不会改变它的值。
因为在不可变类中你永远不需要改变属性/字段状态,所以最好让它成为最终状态。