【问题标题】:Java: Call constructor from another after if statementJava:在if语句之后从另一个调用构造函数
【发布时间】:2019-05-15 20:32:38
【问题描述】:

我有两个构造函数,第一个构造函数创建一些过程,例如创建新对象并且没有 if\for 语句。并且这个构造函数不能被改变,即使是私有的。

但是第二个构造函数得到一个 int 值并且工作起来像 如果为负抛出异常 如果肯定做一些过程 但是如果 num=0 避免重复代码我想调用第一个构造函数。

实现这样的代码的正确方法是什么?请注意,这些构造函数在同一个类中。

public class SomeClass{

  public SomeClass() {
    //Do some process
  }

  public SomeClass(int num) {  
    if (num == 0) {
        this(); //here we have an issue
    }
  }
}

【问题讨论】:

  • 调用当前类的构造函数必须是它的另一个构造函数中的第一个语句。
  • 您可能希望将第一个构造函数中的代码移动到新的私有方法中。然后在 num=0 的情况下从第二个构造函数调用此方法
  • @Arnaud 我知道,这就是我发布这个问题的原因。我无法从第一行调用,因为我需要检查 num 是否等于零。只有在这种情况下,我才想调用第一个构造函数。
  • firstConstructorsecondConstructor 不能都是构造函数,因为它们不能都与类同名。
  • @luk2302 我猜 OP 知道这一点。我编辑了问题,这样事情就更清楚了

标签: java constructor


【解决方案1】:

反过来做:

public class SomeClass{

  public SomeClass() {
    this(1 /* or some sensible default */);
  }

  public SomeClass(int num) {
    // Do stuff.
  }
}

作为一般原则,您应该只拥有一个实际上“做有用的事情”的构造函数。其他重载只存在于提供合理的默认值来调用该构造函数。

【讨论】:

    【解决方案2】:

    创建某种工厂:

    public class SomeClass
    {
      // This is the original constructor
      public SomeClass()
      {
        // Do some process
      }
    
      // New constructor expecting num > 0
      private SomeClass(int num)
      {
        // Do whatever you want
      }
    
      public static SomeClass getIt(int num) throws Exception
      {
        if (num < 0)
          throw new Exception("...");
        else if (num > 0)
          return (new SomeClass(num));
        else
          return (new SomeClass());
      }
    
    } // SomeClass
    

    【讨论】:

    • 谢谢,为什么将第二个构造函数声明为私有的?它应该是公开的
    • 我喜欢这个解决方案,但是我们缺少一点东西。如果我从第二个构造函数调用 getIt 方法,并且我们的 num > 0,我们会一次又一次地调用同一个构造函数。我认为你错过了 getIt 方法中的 return 语句,但这是可以纠正的。
    • 回答“为什么将第二个构造函数声明为私有?”;类的私有成员可以被类静态或非静态的任何方法访问。
    • getIt 方法应该从类外部调用,而不是由第二个构造函数调用。不过,我没有看到缺少的 return 语句。
    • 构造函数是私有的,以便强制类的用户调用工厂方法。
    【解决方案3】:

    在构造函数中必须首先调用另一个构造函数 (this();)。

    您可能想要重构代码,将“处理”逻辑放入方法中:

    public Constructor() {
        this.processConstructor();
    }
    
    public Constructor(int num) {
        if(num == 0) {
            this.processConstructor();
        }
    }
    
    private void processConstructor() {
        //Do some process
    }
    

    【讨论】:

    • 你打败了我! :) 如果我是你,我会将 processConstructor() 的名称更改为 executeProcess(),只是为了理解解决方案。
    • 正如我在帖子中所说,我无法更改第一个构造函数中的任何处理逻辑。我只能编辑第二个并创建新方法。所以在这种情况下,这没有用。请注意,第一个构造函数仅在 num 等于 0 时调用,在其他情况下我有另一个逻辑过程。
    猜你喜欢
    • 2015-07-20
    • 2016-07-03
    • 2010-09-22
    • 2011-03-24
    • 2015-07-02
    • 2011-01-23
    • 1970-01-01
    相关资源
    最近更新 更多