为什么我可以更改私有final ArrayList <book>?</book>

时间:2013-10-17 10:16:54

标签: java arraylist

我的课程看起来像这样:

public class InformationSystem {
    private final ArrayList<Book> books;
    private final ArrayList<Reader> readers;

    public InformationSystem() {
        books = new ArrayList<Book>();
        readers = new ArrayList<Reader>();
    }

    public void addBook(final String author, final String title) {
        Book book = new Book(author, title);
        books.add(book);
    }
}

为什么我可以在最终的arraylist中添加/删除值?

7 个答案:

答案 0 :(得分:15)

我无法改变汽车,我仍然可以更改其中的部件:)

来自Language specification # chapter 14.12.4

  

一旦指定了最终变量,它总是包含相同的值。如果final变量保存对象的引用,则可以通过对象上的操作更改对象的状态,但变量将始终引用同一对象。

你不能重新assign,你仍然可以改变状态。

简而言之

  books  =newBooksList;   // huh! I'm final, No
  books.add(book);       //ok

答案 1 :(得分:3)

你想要的是使你的列表不可变。请参阅此帖子:java-immutable-collections

或直接查看java.util.Collections.unmodifiableList()方法。

http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html?is-external=true#unmodifiableList%28java.util.List%29

答案 2 :(得分:2)

ArrayList对象的引用是最终的 - 您无法更改该引用,也无法重新分配。

但是,你可以调用object的方法。特别是,即使是这些方法,也会改变对象的状态。

因此,ArrayList个对象可变。另一方面,例如,String个对象是不可变的。你不能改变他们的内部状态。

答案 3 :(得分:1)

您已创建ArrayList类型的书籍对象作为final。 所以,books对象引用了Heap上的ArrayList对象,并且当它被声明为final时,它的引用永远不会改变,但你可以改变对象的内容。 因此,您可以添加/删除ArrayList中定义为final的项目。

答案 4 :(得分:0)

保持对对象的引用最终保持指向对象的链接为final,不能更改。但实际对象的状态可能会改变。

引用变量指向的链接为final,它指向的对象的状态不是final

如果您所指的对象是 不可改变 ,那么您将实现您认为会发生的事情。

答案 5 :(得分:0)

final表示您的引用是不可变的 - 它无法更改。

然而,ArrayList是一个可变(可以改变)的数据结构。

您无法更改books指向的内容,但您可以指向它指向的数据结构。总而言之,您对可变数据结构有一个不可变的引用。

答案 6 :(得分:0)

因为您已将ArrayList变量book声明为最终变量,所以当您可以使用当前对象执行任何操作时,无法将book重新分配给另一个对象。

  ArrayList<Book> book = new ArrayList<Book>();

您不能像以下那样重新分配图书变量。

  ArrayList<Book> book2 = new ArrayList<Book>();  
  book = book2;   

虽然你可以对当前的书籍对象做任何事情,因为你没有改变最终变量的内容,你正在改变最终变量所引用的对象的内容。