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的实现,对吗?我们得到了不受支持的异常,所以我们可以捕获并处理它,酷!是的,这只是为了说明基本的想法。对于一般解决方案,可以使用动态代理。