Builder 实现 Cloneable 并重写clone(),不可变类保留构建器的私有克隆,而不是复制构建器的每个字段。这使得返回新的构建器并创建不可变实例的稍微修改的副本变得容易。
这条路我可以走
MyImmutable i1 = new MyImmutable.Builder().foo(1).bar(2).build();
MyImmutable i2 = i1.builder().foo(3).build();
据说 Cloneable 接口有些破损,但是这是否违反了良好的 java 编码实践,这个构造有什么问题吗?
final class MyImmutable {
public int foo() { return builder.foo; }
public int bar() { return builder.bar; }
public Builder builder() { return builder.clone(); }
public static final class Builder implements Cloneable {
public Builder foo(int val) { foo = val; return this; }
public Builder bar(int val) { bar = val; return this; }
public MyImmutable build() { return new MyImmutable(this.clone()); }
private int foo = 0;
private int bar = 0;
@Override public Builder clone() { try { return (Builder)super.clone(); } catch(CloneNotSupportedException e) { throw new AssertionError(); } }
}
private MyImmutable(Builder builder) { this.builder = builder; }
private final Builder builder;
}
通常,从生成器构造的类没有任何生成器的专业知识。也就是说 Immutable 将有一个构造函数来提供 foo 和 bar 的值:
public final class MyImmutable {
public final int foo;
public final int bar;
public MyImmutable(int foo, int bar) {
this.foo = foo;
this.bar = bar;
}
}
构建器将是一个单独的类:
public class MyImmutableBuilder {
private int foo;
private int bar;
public MyImmutableBuilder foo(int val) { foo = val; return this; }
public MyImmutableBuilder bar(int val) { bar = val; return this; }
public MyImmutable build() { return new MyImmutable(foo, bar); }
}
如果需要,您可以向 MyImmutable 构建器添加一个静态方法,以从现有的 MyImmutable 实例开始:
public static MyImmutableBuilder basedOn(MyImmutable instance) {
return new MyImmutableBuilder().foo(instance.foo).bar(instance.bar);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)