为什么具有不同参数的多个 `this()` 在父构造函数中不起作用?
why multiple `this()` with different argument doesn't work in the parent Constructor?
为什么 this()
需要在构造函数链的第一条语句中?
为什么具有不同参数的多个 this()
在最终构造函数中不起作用?
package thislatest;
public class ThisLatest {
public static void main(String[] args) {
A a1= new A(10,20,30);
a1.display();
}
}
class A
{
int x,b;
static int c;
A(){ System.out.println("constructor chaining1");}
A(int y)
{ //this();
System.out.println("constructor chaining2");
b=y;
}
A(int x,int y)
{
// this(x);
System.out.println("constructor chaining3");
x=x;
x=y;
}
A(int x,int y,int c)
{ this();
this(y);
this(x,y);
x=x; //self reference initialised by previous constructor
b=y; //no need of this keyword since name is different
this.c=c; //current instance variable or A.c=c will also work
}
void display()
{
System.out.println(x+b); //wrong result due to self reference
System.out.println(c+b); //correct reference
}
}
为什么我不能在构造函数中使用多个this()
A(int x,int y,int c)
?
为什么这需要是第一个声明?
只是为了保持语言的流畅性吗?
我是初学者请用简单的术语:)
每个构造函数初始化 class 的单个实例。因此,在构造函数中,您只能调用另一个构造函数。构造函数调用必须是第一个的原因是说您将实例的创建委托给另一个构造函数。否则,如果构造函数的第一行不是另一个构造函数的调用,则实例在第一行执行之前就已经实例化了(即隐式调用 super() )。因此在之后调用构造函数就像在你的构造函数中第二次调用某个构造函数,这显然是非法的,因为构造函数只实例化一个实例
为什么 this() 需要在构造函数链的第一条语句中?:因为 Java 规范要求它! Python 例如允许程序员在任何地方调用超类初始化方法。但是Java不允许。句号。
为什么具有不同参数的多个 this() 在最终构造函数中不起作用? 与上面的答案相同。问 why 没用,想想 how 因为你不会改变语言规范。
所以让我们想想怎么做。您可能有充分的理由调用初始化方法,而不是将其作为构造函数的第一条指令。在那种情况下,只需使用非构造函数初始化方法,并从构造函数中调用这些方法:
class A {
private void init1(int x) {
// do something with x
}
private void init2(int x, int y) {
// do something with x and y
...
init1(x); // eventually call init1 in the middle of init2
...
}
A(int x) {
y = 2 *x + 1;
init2(x, y); // call initialization method in the middle of ctor
}
A(int x,int y) {
// eventually some instructions
init2(x, y);
// eventually other instructions
}
}
在Java语言中,构造函数特殊。如果您不能接受,您将不得不使用其他语言。
不允许在同一个构造函数中调用多个构造函数,但可以将它们链接起来以便一个调用另一个,依此类推。您可以这样做,直到 运行 没有 class 中的构造函数。考虑下面的 class:
public class MyClass() {
public MyClass() {
this(1);
System.out.printf("Calling MyClass()%n");
}
public MyClass(int a) {
this(a, 2);
System.out.printf("Calling MyClass(%d)%n", a);
}
public MyClass(int a, int b) {
System.out.printf("Calling MyClass(%d, %d)%n", a, b);
}
}
以及以下客户端代码:
public class Client() {
public static void main(String[] args) {
new MyClass();
}
}
如果你 运行 上面的代码的输出是:
Calling MyClass(1, 2)
Calling MyClass(1)
Calling MyClass()
上面的输出顺序似乎是错误的,因为 printf()
调用是在构造函数调用之后完成的。按照下面的箭头,您可以看到构造函数调用的开始位置和最终结束位置:
Object MyClass Client
------ ------- ------
MyClass() <---------- main(String[])
|
V
MyClass(int)
|
V
Object() <--- MyClass(int, int)
如果你想知道最后一个箭头是什么意思:所有Java-classes,包括MyClass
,秘密扩展Object
-class。 MyClass
中的最后一个构造函数实际上是这样的:
public MyClass(int a, int b) {
super();
System.out.printf("Calling MyClass(%d, %d)%n", a, b);
}
您的 class 需要至少一个构造函数来隐式或显式调用 super()
,否则构造函数链将陷入循环。如果发生这种情况,编译器会给你一个错误。
为什么 this()
需要在构造函数链的第一条语句中?
为什么具有不同参数的多个 this()
在最终构造函数中不起作用?
package thislatest;
public class ThisLatest {
public static void main(String[] args) {
A a1= new A(10,20,30);
a1.display();
}
}
class A
{
int x,b;
static int c;
A(){ System.out.println("constructor chaining1");}
A(int y)
{ //this();
System.out.println("constructor chaining2");
b=y;
}
A(int x,int y)
{
// this(x);
System.out.println("constructor chaining3");
x=x;
x=y;
}
A(int x,int y,int c)
{ this();
this(y);
this(x,y);
x=x; //self reference initialised by previous constructor
b=y; //no need of this keyword since name is different
this.c=c; //current instance variable or A.c=c will also work
}
void display()
{
System.out.println(x+b); //wrong result due to self reference
System.out.println(c+b); //correct reference
}
}
为什么我不能在构造函数中使用多个this()
A(int x,int y,int c)
?
为什么这需要是第一个声明?
只是为了保持语言的流畅性吗?
我是初学者请用简单的术语:)
每个构造函数初始化 class 的单个实例。因此,在构造函数中,您只能调用另一个构造函数。构造函数调用必须是第一个的原因是说您将实例的创建委托给另一个构造函数。否则,如果构造函数的第一行不是另一个构造函数的调用,则实例在第一行执行之前就已经实例化了(即隐式调用 super() )。因此在之后调用构造函数就像在你的构造函数中第二次调用某个构造函数,这显然是非法的,因为构造函数只实例化一个实例
为什么 this() 需要在构造函数链的第一条语句中?:因为 Java 规范要求它! Python 例如允许程序员在任何地方调用超类初始化方法。但是Java不允许。句号。
为什么具有不同参数的多个 this() 在最终构造函数中不起作用? 与上面的答案相同。问 why 没用,想想 how 因为你不会改变语言规范。
所以让我们想想怎么做。您可能有充分的理由调用初始化方法,而不是将其作为构造函数的第一条指令。在那种情况下,只需使用非构造函数初始化方法,并从构造函数中调用这些方法:
class A {
private void init1(int x) {
// do something with x
}
private void init2(int x, int y) {
// do something with x and y
...
init1(x); // eventually call init1 in the middle of init2
...
}
A(int x) {
y = 2 *x + 1;
init2(x, y); // call initialization method in the middle of ctor
}
A(int x,int y) {
// eventually some instructions
init2(x, y);
// eventually other instructions
}
}
在Java语言中,构造函数特殊。如果您不能接受,您将不得不使用其他语言。
不允许在同一个构造函数中调用多个构造函数,但可以将它们链接起来以便一个调用另一个,依此类推。您可以这样做,直到 运行 没有 class 中的构造函数。考虑下面的 class:
public class MyClass() {
public MyClass() {
this(1);
System.out.printf("Calling MyClass()%n");
}
public MyClass(int a) {
this(a, 2);
System.out.printf("Calling MyClass(%d)%n", a);
}
public MyClass(int a, int b) {
System.out.printf("Calling MyClass(%d, %d)%n", a, b);
}
}
以及以下客户端代码:
public class Client() {
public static void main(String[] args) {
new MyClass();
}
}
如果你 运行 上面的代码的输出是:
Calling MyClass(1, 2)
Calling MyClass(1)
Calling MyClass()
上面的输出顺序似乎是错误的,因为 printf()
调用是在构造函数调用之后完成的。按照下面的箭头,您可以看到构造函数调用的开始位置和最终结束位置:
Object MyClass Client
------ ------- ------
MyClass() <---------- main(String[])
|
V
MyClass(int)
|
V
Object() <--- MyClass(int, int)
如果你想知道最后一个箭头是什么意思:所有Java-classes,包括MyClass
,秘密扩展Object
-class。 MyClass
中的最后一个构造函数实际上是这样的:
public MyClass(int a, int b) {
super();
System.out.printf("Calling MyClass(%d, %d)%n", a, b);
}
您的 class 需要至少一个构造函数来隐式或显式调用 super()
,否则构造函数链将陷入循环。如果发生这种情况,编译器会给你一个错误。