Java 如何使可变对象变为不可变对象?(不在创建时)

Java 如何使可变对象变为不可变对象?(不在创建时),java,immutability,Java,Immutability,我有一个用例,我需要首先创建一个(可变的)对象,在某些场景中,我需要使其不可变(我不想在创建时使其不可变)。有没有一个好的方法来实现它? 要求是在某个时候将它从可变变为不可变,使用final将不起作用。很快就说:所有成员都必须声明为final,所有成员类型也必须是不可变的。对象不能同时可变和不可变。您可以在可变对象中使用一个方法来返回相应的不可变对象 下面是一个实现我所说内容的示例 class BasicMutable { private int i; public void

我有一个用例,我需要首先创建一个(可变的)对象,在某些场景中,我需要使其不可变(我不想在创建时使其不可变)。有没有一个好的方法来实现它?
要求是在某个时候将它从可变变为不可变,使用final将不起作用。

很快就说:所有成员都必须声明为final,所有成员类型也必须是不可变的。

对象不能同时可变和不可变。您可以在可变对象中使用一个方法来返回相应的不可变对象

下面是一个实现我所说内容的示例

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

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

有许多库可以为您完成这项工作(我自己没有使用它们)

[1]

[2]

这两个图书馆各有优缺点

[1] 看起来非常轻量级和简单,允许您定义自己的
查询
接口(定义不可变的方法)

[2] 看起来非常成熟,功能齐全,提供了构建器、JSON/GSON支持等

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


这不是我要问的。。。通过这种方式,对象被创建为不可变的,但我的要求是,有时我可以使其不可变。并且类必须禁止子类化。否则你可以创建一个可变的子类。yap,这也是我提出的一个解决方案,我在想是否有可能通过可变的子类来构建一个不变的对象,我们可以使用任何库吗?据我所知,没有库可以使自定义类在运行时不可变,并在需要时返回可变。这基本上是构建器模式。它们与guava的immutableXXX相比如何?它们不仅仅局限于集合。我不喜欢此解决方案中的耦合。如果Mutable被更新为包含一个新的变异方法,那么开发人员必须知道他们也需要修改ImmutableWrapper我认为这个想法类似于guava的immutableXXX的实现,对吗?我们得到了不受支持的异常,所以我们可以捕获并处理它,酷!是的,这只是为了说明基本的想法。对于一般解决方案,可以使用动态代理。