Java构造函数链式调用

4

嗨,我正在学习Java中的构造函数链,有一些问题想问...

  1. First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.

  2. In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?

    import java.util.*;
    
    class Employee
    {   
        private String name;
        private double salary;
    
        public Employee()
        {
            this("James Bond", 34000);
        }
    
        public Employee(String n, double s)
        {
            name = n;
            salary = s;
        }
    
        public String getName()
        {
            return name;
        }
    
        public double getSalary()
        {
            return salary;
        }
    
        public static void main(String[] args)
        {
            Employee a = new Employee();
        }
    }
    

无论您是否链接构造函数,都只会创建一个“Employee”的实例。链接构造函数的目的是防止重复逻辑,尽管您也可以使用从各种构造函数中调用的初始化方法。 - Dave Newton
5个回答

7

实际上,我认为链式构造函数最常见的用法是当构造函数不仅仅是设置成员变量时使用。

static int numOfExamples = 0;
public Example(String name, int num)
{
    this.name = name;
    this.num = num;
    numOfExamples++;
    System.out.println("Constructor called.");
    Log.info("Constructor called");
}

public Example()
{
    this("James Bond",3);
}

那样,我们就不需要两次编写记录和递增静态变量的代码,只需链接构造函数即可。

4

像这样链接构造函数非常有用,可以避免重复代码,并有助于可维护性:

public MyClass(int x, double y, String z) {
    // set fields
}

public MyClass() {  // i.e. a constructor that uses default values
    this(42, 4.2, "hello world");  // x is 42, y is 4.2, and z is "hello world"
}

如果我们不使用链式调用,想要改变在构造MyClass实例时如何处理x参数(例如),我们必须更改两个构造函数中的代码。有了链式调用,我们只需要更改其中一个。

我需要花一些时间让它在脑海中沉淀。我仍然不明白为什么一个人不能只用带有3个参数的构造函数。 - jimbo123
3
他们可以这样做,但如果他们希望字段填充它们的“默认”值,为什么要这样做呢? - arshajii

2

1) 正如其他人所说,这是为了代码维护。基本上,想法是你只需编写一次代码,这意味着你只需要编辑一次,没有风险在编辑方法时忽略某些内容,而导致两者不同。

就个人而言,我倾向于与你的示例不同的用法。例如:

Employee() {
    setupStuff();
}

Employee(String name) {
    this();
    this.setName(name);
}

这是一种很好的做事方式,因为你的setter可能比在类中设置成员更复杂。所以基本上它所做的就是将调用空构造函数和setter合并成一个方法,使得任何使用该类的人都更容易。

2)被调用的构造函数根本不会创建一个不同的对象,而是创建这个对象。请注意,没有使用new关键字。基本上你只是在构造函数内部调用另一个方法,除了这个方法也恰好是一个构造函数。


1
  1. 每当您想要允许使用默认值构造对象,并且还想允许使用非默认值创建相同的对象时。想象一下一个DateTime类。您可以希望默认情况下使用当前时间进行初始化,或者使用特定时间进行初始化。想象一下一个Car类。您可以想象用黑色作为默认颜色来构造它,或者使用特定颜色来构造它。这种情况非常普遍。具体示例请参见java.util.ArrayListjava.util.Locale

  2. 它存储在name字段中。因此,您可以通过对象本身使用this.namethis是可选的,就像getName()方法一样)来访问它。


0

如何访问这个新的“詹姆斯·邦德”对象以备将来使用?

因为您将姓名和薪水的值保存为员工类的字段,所以在员工类内部,您可以使用这些字段,在员工类外部,您可以使用员工类的getter/setter方法。


但是原始对象呢?例如,当我不带参数调用构造函数时,应该创建一个普通对象和“詹姆斯·邦德”对象,对吧? - jimbo123
3
不。将构造单个对象。无参构造函数只是代理有参数的构造函数,以创建单个对象。 - JB Nizet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接