问题
I have a use case where I need to create a (mutable)object first, and at certain scenario I need to make it immutable(I don't wanna make it immutable upon creation). Is there a good way to achieve it? The requirement is to change it from mutable to immutable at some time, using final will not work.
回答1:
An object cannot be mutable and immutable at the same time. What you can do is you can have a method in your mutable object to return corresponding immutable object.
Here is an example of implementation of what I am saying.
class BasicMutable {
private int i;
public void setI(int i){
this.i = i;
}
public void getI(){
return i;
}
public BasicImmutable getImmutable(){
return new BasicImmutable(this);
}
}
Now create Immutable object
class BasicImmutable {
private final i;
BasicImmutable(BasicMutable bm){
this.i = bm.i;
}
public void getI(){
return i;
}
}
You can also have a getMutable() method in BasicImmutable to get corresponding Mutable object.
回答2:
There are a number of libraries, that might do the job for you (I haven't used them myself).
https://github.com/verhas/immutator [1]
http://immutables.github.io [2]
Both libraries have their advantages and disadvantages.
[1] seems to be very lightweight and simple and allows you to define your own Query interface (which defines the immutable methods).
[2] seems to be very mature and feature complete and provides builders, JSON/GSON support etc.
回答3:
public class Mutable {
private int member;
public Mutable(int member) {
this.member = member;
}
public int getMember() {
return member;
}
public void setMember(int member) {
this.member = member;
}
}
public class ImmutableWrapper extends Mutable {
private Mutable mutable;
public ImmutableWrapper(Mutable mutable) {
super(0); // dummy filling
this.mutable = mutable;
}
@Override
public int getMember() {
return mutable.getMember();
}
@Override
public void setMember(int member) {
throw new UnsupportedOperationException();
}
}
public static void main(final String[] args) {
Mutable mutable = new Mutable(1);
mutable = new ImmutableWrapper(mutable);
mutable.getMember();
try {
mutable.setMember(8);
} catch (final Exception e) {
System.out.println(e);
}
}
Output:
java.lang.UnsupportedOperationException
回答4:
Shortly said: All members have to be declared final and all memeber types have to be immutable too.
来源:https://stackoverflow.com/questions/37291294/how-to-make-a-mutable-object-to-immutable-not-at-creation