使用“this”和“super”来调用构造函数

时间:2014-12-29 07:22:27

标签: java constructor this

我有两个问题,分别在构造函数中使用“this”和“super”。

如果从另一个构造函数调用重载的构造函数,那么调用语句 this(......)是第一个吗?我听说否则会出现编译错误。

如果从派生类构造函数内部调用基类构造函数,建议(非强制)调用语句 super(.....)是第一个吗?我听说否则编译器会插入一个没有参数的默认 super(),并将其作为第一个语句。

如果上述概念属实,似乎编译器对“this”更严格,对“super”更灵活。

3 个答案:

答案 0 :(得分:2)

  

如果从另一个构造函数调用重载的构造函数,那么“this”语句必须是第一个吗?我听说否则会出现编译错误。

如果您尝试使用其他构造函数初始化对象字段并通过this(...)调用它,那么它需要是调用构造函数的第一个语句

  

如果从派生类构造函数内部调用基类构造函数,建议(非强制)“super”语句是第一个吗?我听说否则编译器会插入super()并将其作为第一个语句。

  

如果上述概念属实,似乎编译器对“this”更严格,对“super”更灵活。

在创建子类的实例时,无论如何都要初始化超类的字段,因此需要隐式调用默认构造函数

答案 1 :(得分:2)

任何构造函数的第一个语句总是super()(隐式); 除非您将第一行显式调用super()构造函数添加到this()构造函数。

这由JLS-8.8.9. Default Constructor涵盖(部分)

  

如果一个类不包含构造函数声明,则隐式声明一个没有形式参数且没有throws子句的默认构造函数。

     

如果声明的类是原始类Object,则默认构造函数具有空体。否则,默认构造函数只调用不带参数的超类构造函数。

     

如果默认构造函数是隐式声明的,但是超类没有可访问的构造函数(§6.6)且没有参数且没有throws子句,那么这是一个编译时错误。

答案 2 :(得分:1)

如果有一个this(...);调用一个构造函数调用另一个构造函数,它必须首先出现在正文中。

如果有一个super(...);调用构造函数来调用超类的构造函数,它也必须首先出现在正文中。 (您不能包含其他一些语句,然后调用super(...)。)所以这真的不比this(...)的规则更灵活。如果根本没有super(...),而没有this(...),则会有一个隐式super(),没有参数,作为正文的第一个语句插入。如果超类定义构造函数但没有定义无参构造函数,那么子类构造函数必须super(...)调用[或this(...)]开头,否则编译器将给你一个错误:

public class Class1 {
    public Class1(int arg) { ... }
    public Class1(String arg) { ... }
}

public class Class2 {
    public Class2() {
        // The body MUST start with this "super" statement:
        super(<something>);
        // where the argument can be converted to an int or String, or else it's
        // an error!  (Exception: it can start with a this() to call another constructor
        // defined for Class2.)
    }
}