在超类中隐式调用无参构造函数

3
这段内容摘自:http://docs.oracle.com/javase/tutorial/java/IandI/super.html 注意:如果一个构造函数没有显式调用超类的构造函数,Java编译器会自动插入对超类无参构造函数的调用。如果超类没有无参构造函数,则会出现编译时错误。Object类有这样的构造函数,因此如果Object是唯一的超类,则没有问题。
我制作了这个小例子来测试这个规则:
class P作为超类(它是一个空类):
package org.standro.com.pk1;


public class P {
}

在不同的包中有类N,类N继承了类P但未显式调用super():

import org.standro.com.pk1.P;


public class N extends P {

    public N() {
        //imlicitly super() is called here .. that means the constructor of P 

    }

    public static void main(String[] arg){
    N n=new N();

    }
}

没有编译错误...我正在使用JDK1.7。这个例子有什么问题,为什么我没有得到错误?

我认为上面加粗的句子应该是:

如果超类没有任何一个构造函数......

因为如果至少有一个构造函数......编译器会报错......

或者请问是否有解释......谢谢。


3
你不需要为你的类提供任何构造函数,但是要小心。对于没有构造函数的任何类,编译器会自动提供一个无参默认构造函数。由于你没有为你的类P指定构造函数,所以编译器已经为你添加了无参构造函数,因此你的N类中的隐式super();调用是有效的。 - Alexis C.
说编译器会添加无参构造函数意味着构造函数不存在...所以根据上面的粗体句子,为什么没有编译时错误? - Maher Abuthraa
我不明白你的意思。P类有一个无参构造函数。如果查看您的P类生成的字节码,您将会看到它。 - Alexis C.
这正是我在寻找的..因此我想知道为什么不澄清这句话并重写为:如果超类没有无参构造函数且有(至少)一个参数构造函数...那么编译器会抱怨..我是对的吗? - Maher Abuthraa
2个回答

6

由于类P扩展了object,并且没有构造函数,因此它的构造函数默认为无参数构造函数,该构造函数隐式调用Object中的构造函数。

要引发错误,您需要向P的构造函数添加一个参数,如下所示:

public class P {

    public P(int a) {
    }
}

现在N试图隐式调用super(),以在P中查找无参构造函数。然而,由于我们在P中添加了一个构造函数,因此不能再使用默认的无参构造函数。
澄清: 如果没有构造函数,则会添加默认的无参构造函数。如果有任何类型的构造函数,则不会添加默认的无参构造函数。

我理解了...但是句子"If the super class does not have a no-argument constructor"仍然有歧义,我可以理解为超类有无参构造函数,但它还有另一个带参数的构造函数,在这种情况下我可能会犯错误,但也可以理解为根本没有构造函数,因此编译器将添加无参构造函数并且不会出现错误..我是对的吗? - Maher Abuthraa
是的。如果没有构造函数,则会添加默认的无参构造函数。如果有任何类型的构造函数,则不会添加默认的无参构造函数。 - Anubian Noob

1
根据您的解释,如果子类没有调用超类构造函数,则编译器会自动插入对超类无参构造函数的内部调用。
因此,在N类中,您有一个N()构造函数,并且它在内部调用P类的无参构造函数。
而P内部调用Object类的无参构造函数。
因此,您的代码将成功编译。
只有当超类中没有相应的构造函数时,才会出现问题。
因此,请尝试在基类中放置一些带参数的构造函数P(例如p(int x){})并运行程序。由于超类中没有无参构造函数,您肯定会遇到错误。
注意:仅当类中没有构造函数时才会插入无参构造函数。

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