是否可以从另一个(在同一类中,而不是从子类中)调用构造函数?如果是,怎么办?调用另一个构造函数的最佳方法是什么(如果有几种方法)?


当前回答

是的,可以使用this()从另一个构造函数调用一个构造函数

class Example{
   private int a = 1;
   Example(){
        this(5); //here another constructor called based on constructor argument
        System.out.println("number a is "+a);   
   }
   Example(int b){
        System.out.println("number b is "+b);
   }

其他回答

我更喜欢这种方式:

    class User {
        private long id;
        private String username;
        private int imageRes;

    public User() {
        init(defaultID,defaultUsername,defaultRes);
    }
    public User(String username) {
        init(defaultID,username, defaultRes());
    }

    public User(String username, int imageRes) {
        init(defaultID,username, imageRes);
    }

    public User(long id, String username, int imageRes) {
        init(id,username, imageRes);

    }

    private void init(long id, String username, int imageRes) {
        this.id=id;
        this.username = username;
        this.imageRes = imageRes;
    }
}

关键字this可用于从构造函数调用构造函数,当为一个类编写多个构造函数时,有时您希望从另一个构造函数调用一个构造函数以避免重复代码。

Bellow是一个链接,我解释了关于构造函数和getters()和setters()的其他主题,我使用了一个包含两个构造函数的类。我希望这些解释和例子对你有所帮助。

Setter方法或构造函数

[注:我只想添加一个方面,这是我在其他答案中没有看到的:如何克服this()必须位于第一行的要求的限制。]

在Java中,可以通过this()从构造函数调用同一类的另一个构造函数。但是请注意,这必须在第一行。

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, 0.0);
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }
}

这必须出现在第一行看起来是一个很大的限制,但您可以通过静态方法构造其他构造函数的参数。例如:

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, getDefaultArg3(argument1, argument2));
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }

  private static double getDefaultArg3(double argument1, double argument2) {
    double argument3 = 0;

    // Calculate argument3 here if you like.

    return argument3;

  }

}

使用此(参数)。首选模式是从最小构造函数到最大构造函数。

public class Cons {

    public Cons() {
        // A no arguments constructor that sends default values to the largest
        this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
    }

    public Cons(int arg1, int arg2) {
       // An example of a partial constructor that uses the passed in arguments
        // and sends a hidden default value to the largest
        this(arg1,arg2, madeUpArg3Value);
    }

    // Largest constructor that does the work
    public Cons(int arg1, int arg2, int arg3) {
        this.arg1 = arg1;
        this.arg2 = arg2;
        this.arg3 = arg3;
    }
}

您还可以使用最近提倡的valueOf或“of”方法:

public class Cons {
    public static Cons newCons(int arg1,...) {
        // This function is commonly called valueOf, like Integer.valueOf(..)
        // More recently called "of", like EnumSet.of(..)
        Cons c = new Cons(...);
        c.setArg1(....);
        return c;
    }
} 

要调用超级类,请使用super(someValue)。对super的调用必须是构造函数中的第一个调用,否则将出现编译器错误。

它被称为伸缩构造函数反模式或构造函数链接。是的,你肯定可以。我看到了上面的许多示例,我想补充一点,如果你知道你只需要两个或三个构造函数,那可能没问题。但是如果你需要更多,请尝试使用不同的设计模式,如Builder模式。例如:

 public Omar(){};
 public Omar(a){};
 public Omar(a,b){};
 public Omar(a,b,c){};
 public Omar(a,b,c,d){};
 ...

你可能需要更多。在这种情况下,生成器模式将是一个很好的解决方案。这是一篇文章,可能会有所帮助https://medium.com/@型号figuereo/设计图案-2-建筑图案和电梯结构-防图案-60a33de7522e