简体   繁体   中英

Ensuring immutability for mutable objects in immutable list

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM