谁能解释这些构造函数之间的区别。看到这个;
public MyClass() {
}
和
public MyClass() {
this();
}
和
public MyClass() {
super();
}
谁能解释这些构造函数之间的区别。看到这个;
public MyClass() {
}
和
public MyClass() {
this();
}
和
public MyClass() {
super();
}
Second 不允许在 java 中声明,因为您只对默认构造函数进行递归调用。此外,默认情况下,构造函数始终具有 super() 方法,如果未明确指定,编译器将插入该方法。
public MyClass() { }
声明一个空的无参数构造函数。如果您没有为类声明构造函数,编译器会有效地为该类插入此构造函数。
public MyClass() { this(); }
不会编译。
public MyClass() { super(); }
是一个构造函数,它调用超类的默认构造函数。仅当超类具有默认构造函数或没有构造函数时才会编译(在这种情况下,编译器无论如何都会插入默认构造函数,如上所述)。此外,省略super();
呼叫具有相同的效果。
我认为在第二种情况下,您可能打算写:
public MyClass() {
super(); // not "this();"
}
无论哪种方式,您的第二种情况都是编译错误。JLS 是这样说的:
“构造函数通过一系列涉及此的一个或多个显式构造函数调用直接或间接调用自身是编译时错误。” JLS 8.8.7
在您的示例中,this()
是直接调用相同构造函数的显式构造函数调用。
最后,第一种和第三种形式之间没有语义差异。第一种形式隐式调用超类的无参数构造函数,第三种 for 只是使调用显式。
为了可读性,有些人更喜欢使用显式调用来编写表单,但 IMO 并没有真正的区别。
这很简单
让我让你明白
第一的
public MyClass() { }
只是一个默认的公共构造函数
但是当你写这个
public MyClass() { this(); }
这意味着您正在应用构造函数链接。构造函数链接只是调用同一类的另一个构造函数。这必须是构造函数的第一条语句。但是在您的场景中,您没有传递任何内容,this();
这意味着您再次调用相同的构造函数,这将导致无限循环。你的类可能有另一个这样的构造函数
public MyClass(int a) { }
那么你可能称之为
public MyClass(){ this(10); }
上面的语句将使您跳转到接收与您传递的相同参数的构造函数
现在,
public Myclass(){ super(); }
表示您正在调用该类继承的超类的构造函数MyClass
。同样的情况发生在这里,你没有传递任何东西super();
,它将调用 Super 类的默认构造函数。
让我们一一看一下三种类型的构造函数调用。每一种都有与之相关的特殊用途。但这个概念很简单,探索起来也很有趣。
案例 1 :- 这是没有参数的默认构造函数
public class MyClass{
public MyClass(){
}
}
如果你不写,编译器会自动为你提供一个无参数的构造函数。因此,如果你写public class MyClass{ }
.
这相当于写
public class MyClass{
MyClass(){ }
}
需要注意的点:-
当您不使用 super“作为构造函数的第一行”时,编译器会自动提供“super”。注意:- 对于在构造函数中使用的“super”和“this”,请始终将它们写在构造函数代码的第一行,否则编译器会出错。
即使您不在这里扩展 MyClass,编译器也会调用超级 Object 类的构造函数,它是您创建的每个类的根类。
案例 2:- 使用“this”。
构造函数使用“this”来引用同一类中具有不同参数列表的另一个构造函数。
public MyClass() {
this();
}
因此,上面的代码将给出编译错误“递归构造函数调用”,因为它正在调用相同的构造函数并最终进入无限循环。要完成这项工作,您可以改为编写
public MyClass(String str){
System.out.println("constructor with arg "+ str);
}
public MyClass(){
this("Cons"); // note that "this" has to be at first line otherwise compiler gives error
System.out.println("constructor with no arg");
}
在这里你可以看到“this”在构造函数中的重要性。它用于从同一函数中的另一个构造函数调用构造函数。
案例 3:- 使用“超级”。Super 用于调用 super 调用的无参数构造函数。案例 1 中已经提到了休息信息。
public MyClass() {
super();
}
this()
将用于调用MyClass()
No-Args 构造函数。
虽然它会Recurssion constructor error
在编译期间给出
例如:
public MyClass{
public MyClass(){
this(5); // Here this(5) will be used to call the MyClass Constructor with
// int value as Parameter
}
public MyClass(int i){
}
}
在第一种情况下,构造函数将插入对超类的无参数构造函数的静默调用,我猜在这种情况下将是 Object 类。在第二种情况下,this() 调用将调用类的无参数构造函数。它有时也会导致错误。
第二个肯定会导致 OutOfMemoryError 异常,因为堆栈溢出由于错误而无法编译,Recursive constructor invocation
因为您从自身调用相同的构造函数。你的意思是写
super();
? 在这种情况下,两种形式是相同的。
public MyClass() {
}
如果存在,将隐式调用基类的默认无参数构造函数。
第一个是默认的空构造函数。它根本什么都不做。如果您没有其他构造函数(带参数),则根本不必定义这种构造函数。如果没有定义构造函数,它会被隐式设为默认值。
第二个调用自身导致递归循环,因此被禁止。
第三个调用超类的默认无参数构造函数,但什么也不做。超类是您的类extends
的来源,或者Object
(如果您未指定extends
关键字,则隐式扩展)。
在构造函数中,您还可以使用 this 关键字调用同一类中的另一个构造函数。这样做称为显式构造函数调用 http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(0, 0, 0, 0);
}
public Rectangle(int width, int height) {
this(0, 0, width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
但是第二个导致递归构造函数调用并且不允许。
public MyClass() { }
--> 这是普通的构造函数,也称为默认构造函数。
public MyClass() {
this();
}
--> 您正在使构造函数递归。不要使用这种方式。好吧,您可以使用this()
like :
public MyClass() {
this(1); // always intitalize to 1
}
public MyClass(int i) {
this.i=i;
}
默认构造函数没有做任何特别的事情。java中的每个类都默认拥有它,直到您编写自己的构造函数,然后您必须再次自己定义它
公共 A() {}
公共A(整数值){}
是带有递归调用的默认构造函数(无效且不应使用)。与this()
您调用默认构造函数。例如,this(5)
您调用一个已定义的构造函数,该构造函数将 int 值作为参数,如 1 中的示例。
公共 A() { 这(5); }
公共A(整数值){}
默认构造函数,它从你的超类调用默认构造函数
抽象类 A { public A() {} }
B 类扩展 A { public B() { /* 调用 A() */ super(); }