Java中super() 和 this() 的区别

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 语句,因此它打印 FlowParent 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/264180.html

(0)
上一篇 2022年6月7日
下一篇 2022年6月7日

相关推荐

发表回复

登录后才能评论