使用 Lombok 从现有对象构建对象

假设我有一个带有 Lombok 注释的类

@Builder
class Band {
String name;
String type;
}

我知道我能做到:

Band rollingStones = Band.builder().name("Rolling Stones").type("Rock Band").build();

有没有一种简单的方法可以使用现有的对象作为模板来创建 Foo 的对象并更改其中一个属性?

比如:

Band nirvana = Band.builder(rollingStones).name("Nirvana");

我在龙目怪的文件里找不到这个。

117658 次浏览

可以使用 toBuilder参数为实例提供一个 toBuilder()方法。

@Builder(toBuilder=true)
class Foo {
int x;
...
}


Foo f0 = Foo.builder().build();
Foo f1 = f0.toBuilder().x(42).build();

来自 文件:

如果使用@Builder 生成构建器来生成您自己的类的实例(除非将@Builder 添加到不返回您自己的类型的方法中,否则情况总是如此) ,那么您可以使用@Builder (toBuilder = true)在您的类中生成一个名为 toBuilder ()的实例方法; 它创建一个新的构建器,从该实例的所有值开始。

免责声明: 我是一个 Lombok 开发人员。

有没有一种简单的方法可以使用现有的对象作为模板来创建 Foo 的对象,并修改其属性的 ? (强调我的)

如果你真的想改变一个属性,那么有一个更好更有效的方法:

@With
class Band {
String name;
String type;
}


Band nirvana = rollingStones.withName("Nirvana");

Wither 不会创建垃圾,但是它只能更改一个字段

withA(a).withB(b).withC(c)....

并产生成吨的垃圾(所有中间结果) ,但比 toBuilder更有效率和更自然。

注意: 旧版本的 Lombok 使用了 @Wither注释。

您可能还希望使用 com.fasterxml.jackson.databind.ObjectMapper复制对象

@AllArgsConstructor
@Setter
class Band {
String name;
String type;
}


ObjectMapper objectMapper = new ObjectMapper(); //it's configurable
objectMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
objectMapper.configure( SerializationFeature.FAIL_ON_EMPTY_BEANS, false );


Band rollingStones = new Band("Rolling Stones", "Rock Band");


Band nirvana = objectMapper.convertValue( rollingStones, Band.class);
nirvana.setName("Nirvana");

它可以很容易地包装在一些实用的方法,可以在整个项目中使用,如 ConvertUtils.clone(rollingStones, Band.class)