我有一个对象:
Object obj = create();
...我需要设置此Object的一些属性:
obj.setParam("7696969", 0x506);
在此过程之后,我需要确保obj
无法修改。
有没有办法将obj
设为final
而不创建另一个复制final Object
的{{1}}?
答案 0 :(得分:11)
考虑为新创建的对象使用Builder设计模式。
FooBuilder builder = new FooBuilder();
builder.setParam(...);
builder.setBar(...);
final Foo myFoo = builder.build();
请注意,尽管myFoo
是最终的,但它的成员字段可能不是。你不应该忘记宣布那些决赛。
答案 1 :(得分:3)
final关键字不会保持对象的内部变量不被修改。所有final关键字都是保持变量不被重新分配。
保持内部不被修改将需要对象本身的特定设计。
无法重新分配内部变量的对象称为不可变对象。您可以使用私有访问修饰符创建不可变对象,并且不创建set
函数。另外,请务必将所有内部变量声明为final
。
Amir对Builder设计的参考是一个很好的建议。具有构建器模式的不可变对象将非常适合您。
答案 2 :(得分:0)
如果你真的需要通过setter分别设置参数,那么你将不得不做一些简单的算法。例如,您可以在对象必须变为不可变时提供布尔标记,在初始化过程之后将该布尔值设置为true,所有设置器将在确定它们是否可以使用新值重置当前值之前检查此布尔值。
当你没有本机机制为你做艰苦的工作时,你必须想出一个能完成这项工作的算法:)
答案 3 :(得分:0)
你想要一个不可变的类。这是一个例子。
class Foo
{
private string s;
private int i;
public Foo(string s, int i)
{
this.s = s;
this.i = i;
}
public string getS() { return s; }
public int getI() { return i; }
}
Builder设计模式通常有点过分。
答案 4 :(得分:0)
不使用Builder模式,您可以做的是
public class MyImmutableClass {
final private String foo;
final private String bar;
public MyImmutableClass(String f, String b) {
this.foo = f;
this.bar = b;
}
// only getters
}
它的工作方式是
如果构造函数中的params数量增加,则构建器模式很方便。您只是使用构建器来使代码更易于维护和读取,但策略几乎相同,即它还允许仅通过内部静态类进行对象操作,并在主/外部类中公开只读(getters)方法
使用构建器的另一个原因可能是您的对象具有一些必需参数和可选参数。
public class Item {
// private fields & getters
public static class Builder {
// same private fields
public Builder(String f, String b) {
// set values
}
...
...
}
}
在这里,您可以使用内部public Builder(String f, String b)
构造函数来获取两个必需参数,将其余部分保留为可选
如果参数的数量较少,我认为第一个策略比实现构建器更好,因为它有代码重复的缺点(构建器需要从外部类复制所有字段)