使用实例初始化程序来处理构造函数重载

时间:2017-08-01 07:55:21

标签: java

我有时会看到一种模式,即构造函数可能不带参数或一个参数。现在,我想知道'更好'方法是将公共代码移动到最定义的构造函数 - 或者在这种情况下使用实例初始化程序。例如,一种始终为每个创建的类生成ID的方法:

 public SomeClass(){
     this("Hello");
 }

 public SomeClass(String s){
     this.s = s;
     this.id = generateId();
 }

而不是这样写:

 {
     this.id = generateId(); // method does not depend on the class
 }

 public SomeClass(){
      this("Hello");
 }

 public SomeClass(String s){
      this.s = s;
 }

使用Instance Initializer的原因是因为我希望在创建类时始终运行该方法,并且将来其他人可能会更改类的构造函数而忘记执行此操作。虽然它不太可能删除实例初始化程序(没有意识到你在做什么)。

但另一方面,我不确定在这种情况下可读性如何。

这些例子有点人为,而非现实世界的例子。

3 个答案:

答案 0 :(得分:3)

  

使用Instance Initializer的原因是因为我想要   始终在创建类时以及将来运行该方法   别人可能会改变班级的建设者而忘记这样做   这个。虽然它不太可能删除初始化器   (没有意识到你在做什么)。

当修改类时,不应该使用一个(使用Instance Initializer)或另一个(构造函数)来避免编码错误。 无论如何,为什么Initializer会为它提供更好的保险?

您想确保构造函数执行其设计的操作吗? 编写一个单元测试来验证这种行为,并在每次构建时自动执行 就是这样。

答案 1 :(得分:1)

我认为这里有合理的解决方案:

 private final Whatever id = generateId();

换句话说:

  • 确保编译器知道应该初始化(所以使用 final
  • 而不是使用init块(相当罕见)只需初始化一次,"就地#34;

答案 2 :(得分:0)

我从未在现实生活中看到过使用instnace初始化程序。 (我实际上确实看到了它,并在这个网站上的一个理论问题中玩了一下)。在现实生活中,您经常可以看到静态初始化程序块:

public class Bla {
  static {
     //do something
  }
  ....
}

对于公共代码,可以做的是拥有一个被所有构造函数调用的名为init()的方法。在您的示例中,它看起来像

 public SomeClass(){
      this("Hello");
 }

 public SomeClass(String s){
      init();
      this.s = s;
 }

  private init()  {
     this.id = generateId(); // method does not depend on the class
 }