I am required to implement an Immutable List interface and modify its methods to ensure immutability of a list.
I think I have managed to do so, but having trouble ensuring such immutability of mutable objects that are found in this list.
Consider the below interface:
public interface ImmutableListInterface<T>{
T get(int index);
}
and its implementation:
public final class ImmutableList<T> implements ImmutableListInterface<T>{
private final List<T> immutableList;
public ImmutableList(List<T> list) {
immutableList = list;
}
@Override
public T get(int index) {
T item;
List<T> temp = new ArrayList<>(immutableList);
try {
//Try retrieving item
item = temp.get(index);
}catch(Exception e) {
System.out.println("Error message: " + e.getMessage());
return null;
}
return item;
}
}
Now if I were to initialise an ImmutableList of type MutableObject, this does not prevent me from modifying a property of MutableObject. As in:
class MutableObject{
public int a;
}
LinkedList<MutableObject> list = new LinkedList<MutableObject>();
MutableObject object = new MutableObject();
object.a = 0;
list.add(object);
ImmutableList<MutableObject> immutable_list = new ImmutableList<MutableObject>(list);
System.out.println("Before:" + immutable_list.get(0).a); //prints 0, as expected
immutable_list.get(0).a = 1;
System.out.println("After:" + immutable_list.get(0).a);//prints 1 - expecting 0
I have tried setting the method get to final, but to no avail.
It seems like I might have overlooked something in my implementation. How can I truly ensure immutability of the list, allowing the object itself to stay Mutable?
The reason of your problem is that the object returned by get()
method is referencing the same object in your actual list. Therefore the changes made to it are applied to your actual list's object.
On the other hand, you cannot ensure immutability of list's contents, you can only ensure that their references are not modified, whereas their values may change.
If you truly want to preserve objects in list and avoid modifying list's contents after get()
, I suggest to return a deep copy of an object in your method. It will return the same object with brand new reference, which will not be linked to your list.
There are several ways to do it, you can find more information in this question
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.