Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Immutable Object with ArrayList member variable - why can this variable be changed?

Tags:

I have got one class with various member variables. There is a constructor and there are getter-methods, but no setter-methods. In fact, this object should be immutable.

public class Example {    private ArrayList<String> list;  } 

Now I noticed the following: when I get the variable list with a getter-method, I can add new values and so on - I can change the ArrayList. When I call the next time get() for this variable, the changed ArrayList is returned. How can this be? I didn't set it again, I just worked on it! With a String this behaviour isn't possible. So what is the difference here?

like image 283
nano7 Avatar asked May 26 '11 10:05

nano7


People also ask

Can you change values of an immutable object?

In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created. This is in contrast to a mutable object (changeable object), which can be modified after it is created.

Is a immutable value that Cannot change?

Most python objects (booleans, integers, floats, strings, and tuples) are immutable. This means that after you create the object and assign some value to it, you can't modify that value. Definition An immutable object is an object whose value cannot change.

Can we modify immutable class in Java?

Immutable class/object is the one whose value cannot be modified. For example, Strings are immutable in Java i.e. once you create a String value in Java you cannot modify it.


1 Answers

Just because the reference to the list is immutable doesn't mean that the list it refers to is immutable.

Even if list was made final this would be allowed

// changing the object which list refers to example.getList().add("stuff"); 

but this would not allowed:

// changing list example.list = new ArrayList<String>();   // assuming list is public 

In order to make the list immutable (prevent also the first line), I suggest you use Collections.unmodifiableList:

public class Example {     final private ArrayList<String> list;      Example(ArrayList<String> listArg) {         list = Collections.unmodifiableList(listArg);     } } 

(Note that this creates an unmodifiable view of the list. If someone is holding on to the original reference, then the list can still be modified through that.)


With a String this behaviour isnt possible. So what is the difference here?

That is because a String is already immutable (unmodifiable) just as the list would be if you turned it into an unmodifiableList.

Comparison:

              String data structure  | List data structure            .-------------------------+------------------------------------. Immutable  | String                  | Collection.unmodifiableList(...)   | -----------+-------------------------+------------------------------------| Mutable    | StringBuffer            | ArrayList                          |            '-------------------------+------------------------------------' 
like image 136
aioobe Avatar answered Sep 21 '22 20:09

aioobe