如何使一个可变对象变为不可变? (不是在创作时)

时间:2016-05-18 05:50:35

标签: java immutability

我有一个用例,我需要首先创建一个(可变的)对象,在某些情况下我需要使它成为不可变的(我不想让它在创建时不可变)。有没有一个很好的方法来实现它? 要求是在某个时间更改,使用final将无效。

4 个答案:

答案 0 :(得分:2)

对象不能同时是可变的和不可变的。你可以做的是你可以在你的可变对象中有一个方法来返回相应的不可变对象。

以下是我所说的实施例子。

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);
    }
}

现在创建不可变对象

class BasicImmutable {
    private final i;

    BasicImmutable(BasicMutable bm){
        this.i = bm.i;
    }

    public void getI(){
        return i;
    }
}

您还可以在getMutable()中使用BasicImmutable方法获取相应的Mutable对象。

答案 1 :(得分:1)

有许多图书馆可能会为您完成这项工作(我自己没有使用过它们)。

https://github.com/verhas/immutator [1]

http://immutables.github.io [2]

两个图书馆各有利弊。

[1]似乎非常轻量级和简单,允许您定义自己的Query接口(定义不可变方法)。

[2]似乎非常成熟,功能齐全,并提供构建器,JSON / GSON支持等。

答案 2 :(得分:0)

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);
    }
}

输出:

  

java.lang.UnsupportedOperationException

答案 3 :(得分:-1)

简短地说:所有成员都必须被宣布为最终成员,所有成员类型也必须是不可变的。