java中所有类的默认超类,java – 什么时候超类没有默认构造函数?

You don’t have to provide any constructors for your class, but you

must be careful when doing this. The compiler automatically provides a

no-argument, default constructor for any class without constructors.

This default constructor will call the no-argument constructor of the

superclass. In this situation, the compiler will complain if the

superclass doesn’t have a no-argument constructor so you must verify

that it does. If your class has no explicit superclass, then it has an

implicit superclass of Object, which does have a no-argument

constructor.

如果你有一个没有显式默认构造函数的超类A,

子类B扩展A,没有明确的默认构造函数,

并且在驱动程序类的主要方法中

一个obj1 = new A();

将创建一个默认构造函数,它将调用Object类的默认构造函数,对吗?

但如果你这样做

B obj2 = new B();

根据教程,将生成B的默认构造函数,构造函数将调用超类的无参构造函数,后者将依次调用Object中的构造函数.

那么什么时候超类没有无参数构造函数呢?

解决方法:

默认构造函数由编译器在您未提供时定义.

所以这

public class A{}

将在某种程度上由编译器表示为:

public class A

public A() {

super(); //invokes Object's default constructor

}

}

由于我对A的定义没有定义明确的构造函数.

在上面的示例中,A隐式地扩展了Object,并且当它执行super()时,编译器会自动调用Object的默认构造函数.任何可能扩展A的类都是如此,例如:

public class B extends A {}

将由编译器实现有点像:

public class B extends A {

public B() {

super(); //invokes A's default constructor

}

}

你可以看到最终将链接Object的默认构造函数,然后是A的默认构造函数,最后是B的默认构造函数.

&GT那么什么时候超类没有无参数构造函数呢?

当您明确定义一个时,它将没有no-arg构造函数.例如,如果我将A的定义更改为

public class A {

public A(String name){}

}

然后A不再有默认构造函数,我不能再这样做了

public class B extends A {

//Uh oh, compiler error.

//Which parent class constructor should the compiler call?

}

现在B必须通过明确说明要使用哪一个来明确地从其父类链接正确的构造函数.例如

public class B extends A {

B() {

super("B"); //Now the compiler knows which constructor to invoke

}

}

Java反编译器演示

事实上,您可以使用JDK附带的工具来演示所有这些. JDK bin目录中有一个名为javap的程序.这是Java Decompiler工具,它允许您查看编译器生成的代码.

您可以编译我的示例然后反编译它们以查看生成的代码,例如

javac A.java

javap A

反编译器会告诉你:

public class A {

A();

}

这清楚地表明编译器添加了一个默认构造函数.

您可以反汇编类以查看字节代码.

javac B.java

javap -c B

它将显示它如何调用父类的默认构造函数

class B extends A {

B();

Code:

0: aload_0

1: invokespecial #1 // Method A."":()V

4: return

}

如果我向A的构造函数添加一个默认参数,您将看到编译器不再提供默认构造函数,它只提供我明确定义的那个:

class A {

A(String name){}

}

然后我就能做到

javac A.java

javap A

它产生了

class A {

A(java.lang.String);

}

这表明您在原始问题中引用的规范中所读到的内容是正确的.

标签:java,class,constructor,inheritance

来源: https://codeday.me/bug/20190823/1697920.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值