`this()`和`new Object()`在重载构造函数内部的区别是什么?

huangapple go评论73阅读模式
英文:

What is the difference between this() and new Object() inside a overloaded constructor?

问题

我有以下的代码:

public Account() { #1
    id = 0;
    balance = 0;
    interestRate = 4.5;
}

public Account(int newId, double newBalance) {
    //this(); - 选项1
    //new Account(); - 选项2
    id = newId;
    balance = newBalance;
}

public Account(int newId) { #2
    new Account();
    id = novoId;
}

当使用 Account account = new Account(int); 创建一个对象时,它会经过 #2 到 #1 再到 #2。

问题在于选项1和选项2似乎产生了相同的行为(通过调试器查看),这似乎有点违反直觉。有人能对此进行解释吗?

英文:

I have the following code:

public Account() { #1
    id = 0;
    balance = 0;
    interestRate = 4.5;
}

public Account(int newId, double newBalance) {
    //this(); - option 1
    //new Account(); - - option 2
    id = newId;
    balance = newBalance;
}

public Account(int newId) { #2
    new Account();
    id = novoId;
}

When creating an Object with Account account = new Account(int); it runs through #2 to #1 to #2.

The question is that option 1 and option 2 seem to render the same behavior (looking through debugger) which seems a bit counter-intuitive. Can somebody shed some light on it?

答案1

得分: 1

这个区别非常重要:this() 会将当前对象的创建/初始化链接到无参数构造函数 Account(),而 new Account() 会使用无参数构造函数 Account() 创建第二个 Account 类型的对象,然后立即丢弃它。

例如,对于:

public Account(int newId) {
    new Account();
    id = novoId;
}

调用 new Account(5),会执行:

  1. 创建类型为 Account 的对象#1
  2. 为对象#1 调用带参数 5 的 Account(int) 构造函数
  3. 创建类型为 Account 的对象#2
  4. 对象#2 调用 Account() 构造函数
  5. 对象#2 设置 id=0、balance=0、interestRate=4.5
  6. (结束步骤 4 的构造函数)
  7. (返回步骤 2 的构造函数)
  8. 为对象#1 设置 id=5
  9. (结束步骤 2 的构造函数调用)

最终结果:创建的对象的 id=5、balance=0(默认值)、interestRate=0(默认值)

而对于:

public Account(int newId) {
    this();
    id = novoId;
}

调用 new Account(5),会执行:

  1. 创建类型为 Account 的对象#1
  2. 为对象#1 调用带参数 5 的 Account(int) 构造函数
  3. 为对象#1 调用 Account() 构造函数
  4. 为对象#1 设置 id=0、balance=0、interestRate=4.5
  5. (结束步骤 3 的构造函数)
  6. (返回步骤 2 的构造函数)
  7. 为对象#1 设置 id=5
  8. (结束步骤 2 的构造函数调用)

最终结果:创建的对象的 id=5、balance=0、interestRate=4.5

因此,一个重要的区别是,在构造函数中使用 this() 时,使用 new Account(int)new Account(int, double) 创建的对象的 interestRate 将被初始化为 4.5,而在构造函数中使用 new Account() 时,它将为 0(假设在声明本身中没有初始化)。

就个人而言,我建议将构造函数更改为:

public Account(int newId, double newBalance) {
    id = newId;
    balance = newBalance;
    interestRate = 4.5;
}

public Account() {
    this(0, 0);
}

public Account(int newId) {
    this(newId, 0);
}

在我看来,这更加清晰,并且建立了明确的初始化顺序。

英文:

The difference is very important: this() will chain the creation/initialization of the current object to the no-argument constructor Account(), while new Account() will create a second object of type Account using the no-argument constructor Account(), and then immediately throw it away.

For example, with:

public Account(int newId) {
    new Account();
    id = novoId;
}

Calling, new Account(5), will do

  1. Create object#1 of type Account
  2. Call constructor Account(int) with 5 for object#1
  3. Create object#2 of type Account
  4. Call constructor Account() for object#2
  5. Set id=0, balance=0, interestRate=4.5 for object#2
  6. (end constructor of step 4)
  7. (return to constructor of step 2)
  8. Set id=5 for object#1
  9. (end constructor call of step 2)

End result: created object has id=5, balance=0 (default), interestRate=0 (default)

With

public Account(int newId) {
    this();
    id = novoId;
}

Calling, new Account(5), will do

  1. Create object#1 of type Account
  2. Call constructor Account(int) with 5 for object#1
  3. Call constructor Account() for object#1
  4. Set id=0, balance=0, interestRate=4.5 for object#1
  5. (end constructor of step 3)
  6. (return to constructor of step 2)
  7. Set id=5 for object#1
  8. (end constructor call of step 2)

End result: created object has id=5, balance=0, interestRate=4.5

So, an important difference is that when you use this() in your constructor, the interestRate of the object you created with new Account(int) or new Account(int, double) will have been initialized to 4.5, but when using new Account() in your constructor, it will be 0 (assuming you don't have an initialization in the declaration itself).

Personally, I would recommend changing your constructors to :

public Account(int newId, double newBalance) {
    id = newId;
    balance = newBalance;
    interestRate = 4.5;
}

public Account() {
    this(0, 0);
}

public Account(int newId) {
    this(newId, 0);
}

That is - in my opinion - more clear, and establish a clear order of initialization.

答案2

得分: 1

看着你的代码,你的意图似乎是,当你创建一个 Account 类的实例时:

Account account = new Account(int);

你想要使用 Account 类中的无参数构造函数来初始化实例,正确的方法是使用第一个选项,即 this()

之所以第一个选项是你想要做的正确方式,是因为:

this();

这将调用无参数构造函数,以继续对新创建的实例进行初始化,但是:

new Account();

将会创建一个 Account 类的新实例,这显然会导致调用无参数构造函数,这可能不是你想要的。

因此,第一个选项将调用无参数构造函数来初始化新创建的 Account 类实例,而第二个选项将创建一个新的 Account 类实例,它将完全不同于首次导致构造函数调用的实例。

英文:

Looking at your code, your intent seems to be that when you create an instance of Account class

Account account = new Account(int);

you want to initialize the instance using the no-argument constructor in Account class and the correct way to do it is using the first option, i.e. this().

Reason why first option is correct way to do what you want is because

this();

this will invoke the no-argument constructor to continue the initialization of the newly created instance but

new Account();

will create a new instance of Account class which will obviously lead to invocation of the no-argument constructor which is probably not what you want.

So, first option will invoke the no-argument constructor to initialize the newly created instance of Account class whereas the second option will create a new instance of Account class that will be completely different from the instance that lead to the invocation of the constructor in the first place.

答案3

得分: 1

两种方法都调用默认构造函数。

  • 使用 "this()" 你在调用当前实例的构造函数
  • 使用 "new Account()" 你通过调用其默认构造函数来创建一个新实例。

第一个选项是正确的,因为我认为你想要设置当前实例的所有变量。

英文:

Both methods call the default constructor.

  • Using "this()" you are calling the constructor of the current instance
  • with "new Account()" you are creating a new instance by calling its default constructor.

The first option is correct, because I suppose you want to set all the variables of the current instance.

huangapple
  • 本文由 发表于 2020年10月23日 22:26:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64501881.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定