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

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中不允许递归构造函数调用。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程