开发者

How can i make a class Immutable if it has a instance variable of java.lang.Object?

开发者 https://www.devze.com 2023-03-29 15:02 出处:网络
final public class ImmutableWithObject { final Object obj; final List myList; ImmutableWithObject(Object obj1, List list)
final public class ImmutableWithObject {

    final Object obj;
    final List myList;

    ImmutableWithObject(Object obj1, List list)
    {
        this.obj = obj1;
        this.myList = ((List) ((ArrayList) list).clone());
    }

    public Object getObj() {
        return this.obj;
    }

    public 开发者_开发问答List getMyList() {
        return (List) ((ArrayList<String>) this.myList).clone();
    }

    public static void main(String[] args) {

        ImmutableWithObject io = new ImmutableWithObject(new Date(), new ArrayList());

        ((Date) io.getObj()).setDate(22);

        System.out.println((Date) io.getObj());
    }
}
o/p : Mon Aug 22 00:50:04 IST 2011

which is incorrect.


Immutable means that once the object has been constructed, its state does not change.

  • Make class final ( which you have already done )
  • Make the instance variables as private and final
  • Dont provide methods that change the state
  • When passing instance variables, send copies instead of original.

From EJ Item 15 <-- Lot more information in there

Classes should be immutable unless there's a very good reason to make them mutable. If a class cannot be made immutable, limit its mutability as much as possible.


You cannot make it immutable since this object cannot create copies of the contents of the list or the Object. Assuming that you mean to have getters for accessing those properties, the properties themselves were created elsewhere and can be changed in code external to this class that has a reference to it.

The only exception to this is if the contents of Object and List are themselves immutable. Then you can create an immutable copy of the list and you would be done.


You can make a copy of the values of the List object. Whoever called it still has that List and can modify it.


Make the member variables private final and copy the parameters:

final class ImmutableWithObject {

    private final Object obj;
    private final List myList;

    public ImmutableWithObject(Object obj1 , List list)
    {
       this.obj = obj1.clone();
       this.list = (List) list.clone();
    }
}

This will not allow any other class to change your internal state and will not allow ImmutableWithobject to change the myList or obj references. However the obj's state as well as the list can still be manipulated internally. As others pointed out, whoever past the list or obj1 to you class, would be able to manipulate it from the outside too. Since there is no equivalent of something like const in C++, we will have to copy the objects to make sure they are not changed from the outside.

Similarly, if there was a getter, it should also only return a copy (or some read-only interface or a read-only wrapper):

 public Object getObj() { return obj.clone(); }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号