任何人都可以解释这些构造函数之间的差异。看到这个;
public MyClass() {
}
和
public MyClass() {
this();
}
和
public MyClass() {
super();
}
答案 0 :(得分:3)
第二个不允许在java中声明,因为你只是对默认构造函数进行递归调用。此外,默认情况下,构造函数始终使用super()方法,如果未明确指定,则由编译器插入。
答案 1 :(得分:2)
public MyClass() { }
声明一个空的无参数构造函数。如果没有为类声明构造函数,则编译器会有效地为该类插入此conrtsuctor。
public MyClass() { this(); }
不会编译。
public MyClass() { super(); }
是一个构造函数,它调用超类的默认构造函数。只有当超类具有默认构造函数或没有构造函数时才会编译(在这种情况下,编译器无论如何都会插入默认构造函数,如上所述)。此外,省略super();
电话会产生同样的效果。
答案 2 :(得分:1)
我认为在第二种情况下你可能意味着写:
public MyClass() {
super(); // not "this();"
}
无论哪种方式,您的第二种情况都是编译错误。 JLS说:
“构造函数通过一系列涉及此的一系列一个或多个显式构造函数调用直接或间接调用自身是一个编译时错误。” JLS 8.8.7
在您的示例中,this()
是一个显式构造函数调用,它直接调用相同的构造函数。
最后,第一种和第三种形式之间没有语义差异。第一种形式有一个隐式调用超类的no-args构造函数,第三种形式只调用显式。
为了便于阅读,有些人更喜欢使用显式调用来编写表单,但是IMO并没有真正发挥作用。
答案 3 :(得分:1)
非常简单
让我让你明白
第一
public MyClass() { }
只是一个默认的公共构造函数
但是当你写这个
public MyClass() { this(); }
这意味着您正在应用构造函数链接。构造函数Chaining只是调用同一个类的另一个构造函数。这必须是构造函数的第一个语句。但是在你的场景中,你在this();
中没有传递任何东西,这意味着你再次调用相同的构造函数,这将导致无限循环。你的类可能有另外一个这样的构造函数
public MyClass(int a) { }
然后你可能已经调用了这个
public MyClass(){ this(10); }
上面的语句将使您跳转到接收已传递的相同参数的构造函数
现在,
public Myclass(){ super(); }
表示您正在调用由类MyClass
继承的超类的构造函数。同样的情况发生在这里,你在super();
中没有传递任何内容,它将调用Super类的默认构造函数。
答案 4 :(得分:1)
让我们逐个查看三种类型的构造函数调用。每个函数都有与之相关的特殊用途。但这个概念很简单,也很有趣。
案例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();
}
因此,上面的代码将给出编译错误“Recursive Constructor Invocation”,因为它调用相同的构造函数并最终将进入无限循环。为了使这项工作,您可以改为编写
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-call的no-arg构造函数。案例1中已经提到了休息信息。
public MyClass() {
super();
}
答案 5 :(得分:0)
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){
}
}
答案 6 :(得分:0)
在第一种情况下,构造函数将向超类的无参数构造函数插入一个静默调用,我猜在这种情况下将是Object类。在第二种情况下,this()调用将调用类的无参数构造函数。它有时也会导致错误。
答案 7 :(得分:0)
第二个肯定是导致OutOfMemoryError异常,因为堆栈溢出由于Recursive constructor invocation
错误而无法编译,因为你从它自己调用相同的构造函数。你的意思是写
super();
?在这种情况下,两种形式都是相同的
public MyClass() {
}
如果存在,将隐式调用基类的默认no-args构造函数。
答案 8 :(得分:0)
第一个是默认的空构造函数。它什么都不做。如果您没有其他构造函数(带参数),则根本不必定义此类构造函数。如果没有定义构造函数,则默认为默认值。
第二个调用自身导致递归循环,因此被禁止。
第三个调用超类的默认no-args构造函数,但不执行任何操作。超类是您的班级extends
或Object
的超类(如果您未指定extends
关键字,则会隐式扩展)。
答案 9 :(得分:0)
在构造函数中,您还可以使用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;
}
}
但是第二个导致递归构造函数调用而不允许。
答案 10 :(得分:0)
public MyClass() { }
- &GT;这是普通的构造函数,也称为默认构造函数。
public MyClass() {
this();
}
- &GT;你正在构造函数递归。不要用这种方式。那么你可以使用this()
之类的:
public MyClass() {
this(1); // always intitalize to 1
}
public MyClass(int i) {
this.i=i;
}
答案 11 :(得分:0)
默认构造函数没什么特别的。 java中的每个类都默认使用它,直到你编写自己的构造函数,然后你必须自己定义它
公开A(){}
public A(int value){}
是对其进行递归调用的默认构造函数(无效且不应使用)。使用this()
调用默认构造函数。例如,使用this(5)
调用一个定义的构造函数,该构造函数将int值作为参数,如1中的示例。
public A(){this(5); }
public A(int value){}
默认构造函数,它从超类
中调用默认构造函数抽象类A { public A(){} }
B级扩展A { public B(){ / *调用A()* / 超(); }