最终字段真的可以防止Java的可变性吗?

时间:2013-02-09 12:08:25

标签: java immutability

来自着名的书Java Concurrency in Practice章3.4.1 最终字段

  

除非他们将所有字段设为私有,这是一种很好的做法   需要更大的可见度[EJ第12项],这是一个很好的做法   所有领域都是最终的,除非他们需要是可变的。

我对Java中最终引用的理解:最终的引用/字段只是阻止该字段被重新初始化,但如果它引用了一个可变对象,我们仍然可以改变它的状态,使其可变。所以我很难理解上面的引用。你觉得怎么样?

5 个答案:

答案 0 :(得分:12)

最终字段阻止您更改字段本身(通过使其“指向”某个其他实例),但如果该字段是对可变对象的引用,则不会阻止您执行此操作:

public void someFunction (final Person p) {
    p = new Person("mickey","mouse"); //cant do this - its final
    p.setFirstName("donald");
    p.setLastName("duck");
}

上面的引用p是不可变的,但引用指向的实际Person是可变的。 当然,你可以使类Person成为一个不可变的类,如下所示:

public class Person {
    private final String firstName;
    private final String lastName;
    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
    //getters and other methods here
}

这些类一旦创建,就无法以任何方式进行修改。

答案 1 :(得分:3)

这句话只说了什么:

  

将所有字段设为最终字段,除非它们需要是可变的

可变字段是一个字段,您可以稍后更改为指向另一个对象。如果字段为final,则仍可引用可变对象(例如java.util.Date)。因此该字段是不可变的(总是指向同一个对象),但这个对象是可变的。

答案 2 :(得分:2)

java final中的

是similer to this:

int *const p=&something //constant pointer.in c++. you can't use this pointer to change something but that something can be changed with its own.

在java中,最终字段无法更改,但是他们引用的对象可能会自行更改。 防爆。 'this'是最终的,您无法为this分配任何内容,但您可以分配给此引用的对象。

从你的问题:

it is a good practice to make all fields final unless they need to be mutable.

为了避免对原创进行任何修改(无论是在逻辑上还是在意外),最好让它们成为最终版本。

答案 3 :(得分:0)

根据Java代码约定,最终变量被视为常量并写入所有Caps,例如

private final int COUNT=10; // immutable -> cannot be changed

使集合引用变量final意味着只能引用,但您可以在集合中添加,删除或更改对象。例如:

private final List Loans = new ArrayList();
list.add(“home loan”);  //valid
list.add("personal loan"); //valid
loans = new Vector();  //not valid

了解详情:http://javarevisited.blogspot.com/2011/12/final-variable-method-class-java.html#ixzz2KP5juxm0

回答你的问题:是的,如果你正确使用它们。

答案 4 :(得分:0)

忽略报价。时不时地使用final制作代码几乎没有任何好处。作者的目标是一个良好的实践,但在大型代码库中,看到最终的一切都会使意图变得模糊不清,使得阅读代码变得更加难以理解 - 并且可能几乎没有任何好处。

两种方法

一般来说,有两所学校。选择你的:

  1. 反对,除非确实需要
  2. 一个是不要使用final,除非你真的希望那些阅读你写的代码的人知道这个字段在某种程度上是特殊的而且不容小觑。

    1. 因为,从来没有一个糟糕的地方可以使用final!
    2. 另一个迷恋final,并希望它到处都是。它不太普遍。 Renauld Waldura成为这个想法的优秀传播者。阅读他的链接条目,标题为“关于最终关键字的最后一句话”,这是一个很好的,深入的阅读。

      可能取决于您使用的Java

      就我而言,我只是想让你知道final已经改变了,而且并不总是不可改变的,因为你可以阅读Heinz Kabutz' Java Specialist Newsletter。他将向您介绍它在不同Javas中的工作方式,随意使用他的代码并检查您使用的Java。