Java 中的命名参数成语

2022-08-31 10:35:36

如何在Java中实现命名参数习语?(特别是对于构造函数)

我正在寻找一种类似Objective-C的语法,而不是JavaBeans中使用的语法。

一个小的代码示例就可以了。


答案 1

我似乎在构造函数中模拟关键字参数的最佳Java习语是Builder模式,在有效的Java第2版中有所描述。

基本思想是有一个 Builder 类,该类具有用于不同构造函数参数的 setter(但通常不是 getter)。还有一种方法。生成器类通常是它用于生成的类的(静态)嵌套类。外部类的构造函数通常是私有的。build()

最终结果如下所示:

public class Foo {
  public static class Builder {
    public Foo build() {
      return new Foo(this);
    }

    public Builder setSize(int size) {
      this.size = size;
      return this;
    }

    public Builder setColor(Color color) {
      this.color = color;
      return this;
    }

    public Builder setName(String name) {
      this.name = name;
      return this;
    }

    // you can set defaults for these here
    private int size;
    private Color color;
    private String name;
  }

  public static Builder builder() {
      return new Builder();
  }

  private Foo(Builder builder) {
    size = builder.size;
    color = builder.color;
    name = builder.name;
  }

  private final int size;
  private final Color color;
  private final String name;

  // The rest of Foo goes here...
}

要创建Foo的实例,请编写如下内容:

Foo foo = Foo.builder()
    .setColor(red)
    .setName("Fred")
    .setSize(42)
    .build();

主要注意事项是:

  1. 设置模式非常详细(如您所见)。可能不值得,除了你计划在很多地方实例化的类。
  2. 编译时无需检查所有参数是否只指定了一次。您可以添加运行时检查,也可以仅将其用于可选参数,并使必需参数成为 Foo 或生成器构造函数的普通参数。(人们通常不担心多次设置相同参数的情况。

您可能还想查看此博客文章(不是由我撰写的)。


答案 2

这是值得一提的:

Foo foo = new Foo() {{
    color = red;
    name = "Fred";
    size = 42;
}};

所谓的双大括号初始值设定项。它实际上是一个具有实例初始值设定项的匿名类。