2

I have class that looks like this :

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

Why can I add/remove values from arraylist that is final?

Marijus
  • 4,195
  • 15
  • 52
  • 87

7 Answers7

15

I can't change the Car, Still I'm able to change the parts inside it :)

From Language specification # chapter 14.12.4

Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

You cannot re assign, still you can change the state.

In short

  books  =newBooksList;   // huh! I'm final, No
  books.add(book);       //ok
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
2

Reference to an ArrayList object is final - you can't change that reference, you can't reassign.

But, you can call object's methods. In particular, even these methods, which change the state of the object.

So, ArrayList objects are mutable. On the other hand, for example, String objects are immutable. You can't change their internal state.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
2

What you want is to make your List immutable. See this post: java-immutable-collections

Or directly look at the java.util.Collections.unmodifiableList() method.

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

Community
  • 1
  • 1
mwhs
  • 5,878
  • 2
  • 28
  • 34
1

You have Created books object of type ArrayList as final. so, books object refers ArrayList Object on the Heap, and as it is declared as final its reference will never change but you can change content of the object. So, you can add/remove the items from ArrayList defined as final.

pnathan
  • 713
  • 3
  • 9
0

Keeping a Reference to an object final keeps the link pointing to the object as final, which cannot be changed. But the state of the actual object can change.

Link to which the reference variable points is final, the state of object to which it points is not final

If the object to which you are referring to is Immutable then you will achieve what you thought would happen.

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
0

final means that your reference is immutable - it cannot change.

However ArrayList is a mutable (can change) data structure.

You cannot change what books points to, but you can the data structure to which it points. In sum, you have an immutable reference to a mutable data structure.

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384
0

Because you have declare the ArrayList variable book as a final variable so you can not reassign book with another object while you can do any thing with the current object.

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

You can not reassign book variable like following.

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

While you can do anything with the current book object because you are not changing the content of final variable you are changing content of object to which final variable is referencing.

Kanchan
  • 870
  • 1
  • 9
  • 20