重载构造函数调用其他构造函数,但不是第一个语句

发布于 2024-09-12 19:06:18 字数 528 浏览 1 评论 0原文

我在 java 中使用多个构造函数时遇到一些问题。

我想做的是这样的:

public class MyClass {

 // first constructor
 public MyClass(arg1, arg2, arg3) {
  // do some construction
 }

 // second constructor
 public MyClass(arg1) {
      // do some stuff to calculate arg2 and arg3
      this(arg1, arg2, arg3);
    }
}

但我不能,因为第二个构造函数不能调用另一个构造函数,除非它是第一行。

对于这种情况,常见的解决方案是什么? 我无法“在线”计算 arg2 和 arg3。我想也许创建一个构造辅助方法,它将完成实际的构造,但我不确定这是否如此“漂亮”...

编辑:使用辅助方法也是有问题的,因为我的一些字段是最终的,我无法使用辅助方法设置它们。

I'm having some trouble using multiple constructors in java.

what I want to do is something like this:

public class MyClass {

 // first constructor
 public MyClass(arg1, arg2, arg3) {
  // do some construction
 }

 // second constructor
 public MyClass(arg1) {
      // do some stuff to calculate arg2 and arg3
      this(arg1, arg2, arg3);
    }
}

but I can't, since the second constructor cannot call another constructor, unless it is the first line.

What is the common solution for such situation?
I can't calculate arg2 and arg3 "in line". I thought maybe creating a construction helper method, that will do the actual construction, but I'm not sure that's so "pretty"...

EDIT: Using a helper method is also problematic since some of my fields are final, and I can't set them using a helper method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

睡美人的小仙女 2024-09-19 19:06:19

通常使用另一种常见方法 - 正如您所建议的“构造助手”。

public class MyClass { 

    // first constructor 
    public MyClass(arg1, arg2, arg3) { 
      init(arg1, arg2, arg3); 
    } 

    // second constructor 
    public MyClass(int arg1) { 
      // do some stuff to calculate arg2 and arg3 
      init(arg1, arg2, arg3); 
    } 

    private init(int arg1, int arg2, int arg3) {
      // do some construction 
    }
} 

另一种方法是工厂式方法,其中您有一个 MyClassFactory,它为您提供 MyClass 实例,并且 MyClass 只有一个构造函数:

public class MyClass { 

    // constructor 
    public MyClass(arg1, arg2, arg3) { 
      // do some construction 
    } 
} 

public class MyClassFactory { 

    public static MyClass MakeMyClass(arg1, arg2, arg3) { 
      return new MyClass(arg1, arg2, arg3);
    } 

    public static MyClass MakeMyClass(arg1) { 
      // do some stuff to calculate arg2 and arg3 
      return new MyClass(arg1, arg2, arg3);
    } 
} 

I绝对更喜欢第一个选择。

Typically use another common method - a "construction helper" as you've suggested.

public class MyClass { 

    // first constructor 
    public MyClass(arg1, arg2, arg3) { 
      init(arg1, arg2, arg3); 
    } 

    // second constructor 
    public MyClass(int arg1) { 
      // do some stuff to calculate arg2 and arg3 
      init(arg1, arg2, arg3); 
    } 

    private init(int arg1, int arg2, int arg3) {
      // do some construction 
    }
} 

The alternative is a Factory-style approach in which you have a MyClassFactory that gives you MyClass instances, and MyClass has only the one constructor:

public class MyClass { 

    // constructor 
    public MyClass(arg1, arg2, arg3) { 
      // do some construction 
    } 
} 

public class MyClassFactory { 

    public static MyClass MakeMyClass(arg1, arg2, arg3) { 
      return new MyClass(arg1, arg2, arg3);
    } 

    public static MyClass MakeMyClass(arg1) { 
      // do some stuff to calculate arg2 and arg3 
      return new MyClass(arg1, arg2, arg3);
    } 
} 

I definitely prefer the first option.

梅倚清风 2024-09-19 19:06:19

下一个可能的解决方案是工厂方法。这些静态方法可以重载,并且在计算后它们可以调用私有/受保护的构造函数

public class MyClass {

    private MyClass( arg1, arg2, arg3 ) {
         // do sth
    }

    public static MyClass getInstance( arg1 ) {
         // calculate arg2,3
        return new MyClass( arg1, arg2, arg3 );
    }

    public static MyClass getInstance( arg1, arg2, arg3 ) {
        return new MyClass( arg1, arg2, arg3 );
    }
}

编辑:当您有最终字段时,此方法也是理想的选择

Next possible solution is Factory method. These static methods can be overloaded and after calculation they can call the private / protected constructor

public class MyClass {

    private MyClass( arg1, arg2, arg3 ) {
         // do sth
    }

    public static MyClass getInstance( arg1 ) {
         // calculate arg2,3
        return new MyClass( arg1, arg2, arg3 );
    }

    public static MyClass getInstance( arg1, arg2, arg3 ) {
        return new MyClass( arg1, arg2, arg3 );
    }
}

EDIT: This method is also ideal when you have a final fields

情深缘浅 2024-09-19 19:06:19

虽然我更喜欢其他几个答案指出的工厂方法选项,但我想建议另一个选项:您可以使用静态方法来计算其他参数:

public class MyClass {
    public MyClass(int arg1, int arg2, int arg3) {
        // do some construction
    }

    public MyClass(int arg1) {
      //call to this() must be the first one
      this(arg1, calculateArg2(arg1), calculateArg3());
      //you can do other stuff here
    }

    private static int calculateArg2(int arg1) {
      //calc arg2 here
    }

    private static int calculateArg3() {
      //calc arg3 here
    }
}

Although I prefer the factory method option pointed to by several other answers, I wanted to suggest another option: You can use static methods to do the calculation of your other parameters:

public class MyClass {
    public MyClass(int arg1, int arg2, int arg3) {
        // do some construction
    }

    public MyClass(int arg1) {
      //call to this() must be the first one
      this(arg1, calculateArg2(arg1), calculateArg3());
      //you can do other stuff here
    }

    private static int calculateArg2(int arg1) {
      //calc arg2 here
    }

    private static int calculateArg3() {
      //calc arg3 here
    }
}
滥情稳全场 2024-09-19 19:06:19

助手和工厂选项非常好。

还有一种:

public MyClass(int arg1) {
    this(arg1, calculateArg2(), calculateArg3());
}

private static int calculateArg2() {..}
private static int calculateArg3() {..}

The helper and factory options are very good.

There is another one:

public MyClass(int arg1) {
    this(arg1, calculateArg2(), calculateArg3());
}

private static int calculateArg2() {..}
private static int calculateArg3() {..}
上课铃就是安魂曲 2024-09-19 19:06:19

使用“缺失”标记值 为了

public class MyClass {
 public MyClass(arg1, arg2, arg3) {
  // do some stuff to calculate arg2 and arg3 if they are the missing values
  // do some construction
 }
 public MyClass(arg1) {
   this(arg1, null, null);
 }
}

获得最佳结果,请将“常规”构造函数设置为受保护私有

Use marker values for 'missing'

public class MyClass {
 public MyClass(arg1, arg2, arg3) {
  // do some stuff to calculate arg2 and arg3 if they are the missing values
  // do some construction
 }
 public MyClass(arg1) {
   this(arg1, null, null);
 }
}

For best results, make the 'general' constructor protected or private.

猥琐帝 2024-09-19 19:06:19

另一种方法是这样的:

public class MyClass {

  // first constructor
  public MyClass(arg1, arg2, arg3) {
   // do some construction
   doSomeStuffToArg3Arg3(arg2, arg3)
  }

  // second constructor
  public MyClass(int arg1) {
      this(arg1, arg2, arg3);
  }

  private void doSomeStuffToArg3Arg3(int arg2, int arg3) {
     // do some stuff to calculate arg2 and arg3
  }
}

Another way is this:

public class MyClass {

  // first constructor
  public MyClass(arg1, arg2, arg3) {
   // do some construction
   doSomeStuffToArg3Arg3(arg2, arg3)
  }

  // second constructor
  public MyClass(int arg1) {
      this(arg1, arg2, arg3);
  }

  private void doSomeStuffToArg3Arg3(int arg2, int arg3) {
     // do some stuff to calculate arg2 and arg3
  }
}
他夏了夏天 2024-09-19 19:06:19

您可以将 MyClass(arg1, arg2, arg3) 的代码移动到辅助方法中(将其命名为 Init 或其他名称),然后在两个构造函数中调用此方法。

You can move the code of MyClass(arg1, arg2, arg3) into helper method (name it Init or something else ) and then call this method in both constructors.

国粹 2024-09-19 19:06:19

作为给出答案的替代方案,最简单的方法是将参数计算重构为 3 参数构造函数;

public class MyClass {

    // first constructor
    public MyClass(arg1, arg2, arg3) {
        if (null == arg2) {
            // calculate arg2
        }
        if (null == arg3) {
            // calculate arg3
        }
        // do some construction
    }

    // second constructor
    public MyClass(arg1) {
        this(arg1, null, null);
    }
}

As an alternative to the answers given, the simplest way is to refactor the argument calculation to the 3 argument constructor;

public class MyClass {

    // first constructor
    public MyClass(arg1, arg2, arg3) {
        if (null == arg2) {
            // calculate arg2
        }
        if (null == arg3) {
            // calculate arg3
        }
        // do some construction
    }

    // second constructor
    public MyClass(arg1) {
        this(arg1, null, null);
    }
}
泅人 2024-09-19 19:06:19

您可以创建一个调用构造函数的 工厂方法

public class MyClass { 

    // first constructor 
    public MyClass(arg1, arg2, arg3) { 
    // do some construction

    } 

    // second constructor as factory method
    public static createMyClassAndDoFunkyStuff(int arg1) { 
      // do some stuff to calculate arg2 and arg3 
      return new MyClass(arg1, arg2, arg3); 
    } 

} 

You could create a factory method which calls the constructor:

public class MyClass { 

    // first constructor 
    public MyClass(arg1, arg2, arg3) { 
    // do some construction

    } 

    // second constructor as factory method
    public static createMyClassAndDoFunkyStuff(int arg1) { 
      // do some stuff to calculate arg2 and arg3 
      return new MyClass(arg1, arg2, arg3); 
    } 

} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文