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


当前回答

可以通过this(…)关键字(当需要从同一类调用构造函数时)或super(…)关键词调用另一个构造函数(当您需要从超类调用构造函数时)。

但是,这样的调用必须是构造函数的第一条语句。要克服这个限制,请使用这个答案。

其他回答

我更喜欢这种方式:

    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;
    }
}

是的,可以从另一个构造函数调用一个构造函数。但这有一个规则。如果从一个构造函数调用另一个构造函数,那么

该新构造函数调用必须是当前构造函数中的第一条语句

public class Product {
     private int productId;
     private String productName;
     private double productPrice;
     private String category;

    public Product(int id, String name) {
        this(id,name,1.0);
    }

    public Product(int id, String name, double price) {
        this(id,name,price,"DEFAULT");
    }

    public Product(int id,String name,double price, String category){
        this.productId=id;
        this.productName=name;
        this.productPrice=price;
        this.category=category;
    }
}

所以,下面这样的东西是行不通的。

public Product(int id, String name, double price) {
    System.out.println("Calling constructor with price");
    this(id,name,price,"DEFAULT");
}

此外,在继承的情况下,当创建子类的对象时,首先调用超级类构造函数。

public class SuperClass {
    public SuperClass() {
       System.out.println("Inside super class constructor");
    }
}
public class SubClass extends SuperClass {
    public SubClass () {
       //Even if we do not add, Java adds the call to super class's constructor like 
       // super();
       System.out.println("Inside sub class constructor");
    }
}

因此,在这种情况下,在任何其他语句之前,也会先声明另一个构造函数调用。

有一些设计模式可以满足复杂构造的需要——如果不能简洁地完成,请创建工厂方法或工厂类。

通过最新的java和lambdas的添加,很容易创建一个可以接受任何初始化代码的构造函数。

class LambdaInitedClass {

   public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
       init.accept(this);
   }
}

称之为。。。

 new LambdaInitedClass(l -> { // init l any way you want });

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

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

Setter方法或构造函数

是的,有可能:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

要链接到特定的超类构造函数而不是同一类中的构造函数,请使用super而不是this。请注意,您只能链接到一个构造函数,并且它必须是构造函数主体中的第一条语句。

另请参阅这个相关的问题,它是关于C#的,但在相同的原则适用的地方。