gpt4 book ai didi

java - 将可变对象转换为不可变对象(immutable对象)

转载 作者:行者123 更新时间:2023-11-30 08:41:12 29 4
gpt4 key购买 nike

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

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

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

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

有没有一种方法可以在运行时更改实例,将字段从 non-final 更改为 final 而无需子类化等。

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

一个漂亮整洁的工厂模式也可能会成功......

最佳答案

Joshua Bloch 在他的书 Effective Java, Second Edition 中的第二章“创建和销毁 Java 对象”中解决了这个问题。 You can view an example taken from his book here :

// 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();

从上面的例子可以看出,你可以先创建一个可变对象,然后再将它构建成一个不可变对象(immutable对象)。对象的构建器也可以调整并重新用于生成多个不可变的对象。例如:

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

关于java - 将可变对象转换为不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213798/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com