super()
和 this()
都用于进行构造函数调用。 super()
用于调用基类的构造函数(即父类),而 this()
用于调用当前类的构造函数。
下面来详细看看它们:
super()
1、super()
用于调用基类(父类)的构造函数。
// Java code to illustrate usage of super() class Parent { Parent() { System.out.println("Parent class's No " + " arg constructor"); } } class Child extends Parent { Child() { super(); System.out.println("Flow comes back from " + "Parent class no arg const"); } public static void main(String[] args) { new Child(); System.out.println("Inside Main"); } }
运行输出结果如下:
Parent class's No arg constructor Flow comes back from Parent class no arg const Inside Main
程序执行流程:
- 在 main 中,我们做了一个
new Child()
语句,所以它调用了Child
类的无参数构造函数。 - 在里面有
super()
调用 Parent 类的无参数,因为编写了super()
并且没有参数,这就是它调用Parent
类的无参数构造函数的原因,因为有一个SOP
语句,因此它打印Parent
类的No arg
构造函数。 - 现在,随着 Parent 类的
No argument const
完成,flow 回到 Child 类的no argument
并且有一个SOP
语句,因此它打印Flow
从Parent class no arg const
返回。 - 在完成子类流的无参数构造函数之后,现在再次回到
main
并执行剩余的语句并在Main
中打印。
2、只能在构造函数内部使用 super()
,在其他任何地方都不能使用,即使在静态上下文中也不能在方法内部使用,并且 super()
应该是构造函数内部的第一个语句。
// Java program to illustrate usage of // super() as first statement class Parent { Parent() { System.out.println("Parent class's No " + "arg constructor"); } } class Child extends Parent { Child() { // Uncommenting below line causes compilation // error because super() should be first statement // System.out.println("Compile Time Error"); super(); System.out.println("Flow comes back from " + "Parent class no arg const"); } public static void main(String[] args) { new Child(); System.out.println("Inside main"); } }
运行输出结果:
Parent class's No arg constructor Flow comes back from Parent class no arg const Inside main
注意:
super()
应该是任何构造函数中的第一个语句。 它只能在构造函数内部使用,不能在其他任何地方使用。super()
仅用于引用父类(超类)的构造函数。
this()
this()
用于调用当前类的构造函数。
// Java code to illustrate usage of this() class RR { RR() { this(10); System.out.println("Flow comes back from " + "RR class's 1 arg const"); } RR(int a) { System.out.println("RR class's 1 arg const"); } public static void main(String[] args) { new RR(); System.out.println("Inside Main"); } }
运行结果:
RR class's 1 arg const Flow comes back from RR class's 1 arg const Inside Main
程序执行流程:
- 首先从
main
开始,然后有一个语句new Child()
因此它调用Child
类的无参数构造函数,在里面有this(10)
它调用当前类的第一个参数(即 RR 类) - 由于编写了
this(10)
和 1 个参数,它调用 RR 类的 1 个参数构造函数。 因为有一个 SOP 语句,因此它打印 RR 类的1 arg const
。 - 随着 RR 类的 1 参数 const 完成,flow 回到 RR 类的无参数,因为有一个 SOP 语句,因此它打印 Flow 从 RR 类的
1 arg const
回来。 - 在完成 RR 类流的无参数构造函数之后,现在再次回到 main 并执行剩余的语句并打印
Inside Main
。
只能在构造函数中使用 this()
而不能在其他任何地方使用,即使在静态上下文中也不能在方法内部使用,并且 this()
应该是构造函数中的第一个语句。
// Java program to illustrate usage of // this() as first statement class RR { RR() { // Uncommenting below line causes compilation // error because this() should be first statement // System.out.println("Compile Time Error"); this(51); System.out.println("Flow comes back from RR " + "class 1 arg const"); } RR(int k) { System.out.println("RR class's 1 arg const"); } public static void main(String[] args) { new RR(); System.out.println("Inside main"); } }
运行结果如下:
RR class's 1 arg constructor Flow comes back from RR class 1 arg const Inside main
注意:
this()
应该是任何构造函数中的第一条语句。 它只能在构造函数内部使用,不能在其他任何地方使用。this()
仅用于引用当前类的构造函数。
关于 this() 和 super() 的要点
- 我们只能在构造函数中使用
super()
以及this()
一次。 如果使用super()
两次或this()
两次,或super()
后跟this()
, 或this()
后跟super()
,那么会立即得到编译时错误,即可以使用super()
或this()
作为构造函数中的第一个语句,但不是同时使用两个。 - 是否使用
super()
或this()
取决于您,因为如果不使用this()
或super()
,则默认情况下编译器会将super()
作为构造函数中的第一条语句。
// Java program to illustrate super() by default // executed by compiler if not provided explicitly class Parent { Parent() { System.out.println("Parent class's No " + "argument constructor"); } Parent(int a) { System.out.println("Parent class's 1 argument" + " constructor"); } } class Base extends Parent { Base() { // By default compiler put super() // here and not super(int) System.out.println("Base class's No " + "argument constructor"); } public static void main(String[] args) { new Base(); System.out.println("Inside Main"); } }
运行结果:
Parent class's No argument constructor Base class's No argument constructor Inside Main
程序执行流程:
- 在 main 有
new Base()
然后流程转到基类的无参数构造函数。 - 之后,如果不放
super()
或this()
代码,那么编译器默认放super()
。 - 所以流程转到
"Parent class’s No arg constructor"
而不是" 1 argument constructor"
。 - 之后它会打印 Parent 类的无参数构造函数。
- 之后,当 Parent() 构造函数完成时,流程再次回到基类的无参数构造函数并执行下一个 SOP 语句,即基类的无参数构造函数。
- 完成无参数构造函数流程后,再次返回
main()
并打印main()
内的剩余语句,即Inside main
。
但是,如果明确指定,可以在 super()
之前使用 this()
。
// Java program to illustrate recursive // constructor call not allowed class RR { RR() { this(30); } RR(int a) { this(); } public static void main(String[] args) { new RR(); } }
运行结果:
Compile time error saying recursive constructor invocation
程序流程:这里,上面从 main() 开始,然后流程转到 RR 类的 No arg 构造函数。 之后,有 this(30)
并且流转到 RR 的 1 arg 构造函数,因为有 this()
所以再次流转到基类的 No arg 构造函数,然后再次有了 this(30)
并再次流 到 Base 类的 1 个 arg 构造函数,它继续……就像一个递归。 所以它是无效的,这就是为什么得到编译时错误:递归构造函数调用。 所以java中不允许递归构造函数调用。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/264180.html