在构建器中对某些字段进行有条件的设置。

问题描述 投票:0回答:2

我有一个带有构建器的遗留Java类--我不能改变这个类。

建构器的一些setter在发生异常时抛出 null 输入。

     public Cat.Builder setOwnerName(String value) {
        if (value == null) {
            throw new NullPointerException();
        } else {
            this.ownerName = value;
            this.onChanged();
            return this;
        }
     }

我正在尝试创建 Cat 从另一个类--使用一个外部对象,这个外部对象可能有,也可能没有。null 相关字段中的值。

  Cat cat = Cat.newBuilder()
            .setXYZ("XYZ")
            .setOwnerName(inputFromUser.getOwnerName())
            .build();

而且由于 inputFromUser.getOwnerName() 有时 null构建者会抛出一个异常。

我试图找到一种优雅的方式来有条件地设置或不设置 ownerName 或任何其他非空字段)。

java conditional-statements builder
2个回答
4
投票
Cat.Builder builder = Cat.newBuilder()
    .setXYZ("XYZ");
Optional.ofNullable(inputFromUser.getOwnerName())
    .ifPresent(builder::setOwnerName);
// repeat above statement for all optional fields
Cat cat = builder.build();

2
投票

你不需要使用调用链来调用一个构建器。

Cat.Builder catBuilder = Cat.newBuilder();
catBuilder.setXYZ("XYZ");
catBuilder.setOwnerName(inputFromUser.getOwnerName());
Cat cat = catBuilder.build();

(你 可能 不要。没有要求Builder方法返回自己,但如果不返回就有点不寻常了)。)

所以,就这样写,在需要的地方放一个条件。

Cat.Builder catBuilder = Cat.newBuilder();
catBuilder.setXYZ("XYZ")
if (inputFromUser.getOwnerName() != null) {
  catBuilder.setOwnerName(inputFromUser.getOwnerName());
}
Cat cat = catBuilder.build();

如果你想更实用一些,你可以写一个像这样的方法。

<T> void consumeIfNonNull(@Nullable T value, Consumer<? super T> consumer) {
  if (value != null) consumer.accept(value);
}

and then do:

consumeIfNonNull(inputFromUser.getOwnerName(), catBuilder::setOwnerName);

我认为这在调用站点上比用一个 Optional但是,每个人都有自己的想法。

© www.soinside.com 2019 - 2024. All rights reserved.