2

我的课看起来像这样:

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);
    }
}

为什么我可以从最终的数组列表中添加/删除值?

4

7 回答 7

15

我不能改变汽车,但我仍然可以改变它里面的零件:)

来自语言规范#第 14.12.4 章

一旦分配了最终变量,它总是包含相同的值。如果最终变量持有对对象的引用,则对象的状态可能会通过对对象的操作而改变,但变量将始终引用同一个对象。

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

简而言之

  books  =newBooksList;   // huh! I'm final, No
  books.add(book);       //ok
于 2013-10-17T10:18:14.093 回答
2

ArrayList对象的引用是最终的——你不能改变那个引用,你不能重新分配。

但是,您可以调用对象的方法。尤其是这些改变对象状态的方法。

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

于 2013-10-17T10:19:29.293 回答
2

你想要的是让你的 List 不可变。看到这篇文章: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

于 2013-10-17T10:20:18.570 回答
1

您已将 ArrayList 类型的书籍对象创建为 final。因此,books 对象引用堆上的 ArrayList 对象,并且由于它被声明为 final,它的引用永远不会改变,但您可以更改对象的内容。因此,您可以从定义为 final 的 ArrayList 中添加/删除项目。

于 2013-10-17T10:28:12.437 回答
0

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

参考变量指向的链接,final它指向的对象的状态不是final

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

于 2013-10-17T10:22:45.780 回答
0

final意味着您的参考是不可变的 - 它不能改变。

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

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

于 2013-10-17T10:25:58.713 回答
0

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

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

您不能像下面这样重新分配 book 变量。

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

虽然您可以对当前 book 对象执行任何操作,因为您没有更改最终变量的内容,但您正在更改最终变量所引用的对象的内容。

于 2013-10-17T10:48:43.313 回答