繁体   English   中英

将可变对象转换为不可变对象

[英]convert a mutable object to an immutable object

我想让 bean 不可变,传统方法是将所有字段设为final并在构造函数中设置它们的值。

在我看来,这很有效,除非有许多字段需要通过一些复杂的逻辑相互依赖计算,或者当多个服务需要参与设置值时。

工厂是另一种方法,但我无法提出避免过多代码的整洁模型。

我想做的是创建 bean 的可变实例,一旦它完全填充,我想“烘焙”它,即使其不可变。

有没有办法在运行时更改实例,将字段从non-final更改为final而不需要子类化等。

我相当肯定它不能仅使用标准的 java/reflection 来完成,但我怀疑使用一些字节码更改(例如 javassist 等)可能是可能的。

一个漂亮整洁的工厂模式也可能会得到勾选......

Joshua Bloch 在他的《 Effective Java, Second Edition》一书中关于“创建和销毁 Java 对象”的第二章中解决了这个问题。 您可以在此处查看他的书中的示例

 // Builder Pattern public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; public static class Builder { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }

使用此对象的示例是:

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

从上面的例子中可以看出,可以先创建一个可变对象,然后再将其构建为不可变对象。 对象的构建器也可以调整和重用以生成多个不可变的对象。 例如:

NutritionFacts.Builder food = new NutritionFacts.Builder(1, 1);
NutritionFacts salad = food.calories(100).build();
NutritionFacts bigMac = food.calories(1000).build();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM