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