Java构造函数奇怪的行为

时间:2013-04-13 13:20:57

标签: java constructor chaining

我已经运行了这段代码

public class Redimix extends Concrete{

    Redimix(){
        System.out.println("r ");
    }

    public static void main(String[] args) {
        new Redimix();
    }

}

class Concrete extends Sand{
    Concrete() { System.out.print("c "); }
    private Concrete(String s) { }
}

abstract class Sand{
    Sand(){
        System.out.print("s ");
    }
}

并打印出s c r,但我所期待的只是r我的问题是什么才是合乎逻辑的解释?

如果父基类是具有构造函数的抽象类,然后我们创建另一个类然后将其扩展到基类(在我们的案例Concrete extends Sand中)然后我们创建另一个类然后扩展它具体的类名称(在我们的例子中是redimix)将调用层次结构中的所有构造函数?(从上到下)

5 个答案:

答案 0 :(得分:6)

超类的构造函数始终被调用为构造函数的第一个动作。

如果您没有显式调用超类的构造函数,则会隐式调用默认构造函数(“no args”构造函数)。

答案 1 :(得分:3)

这是正确的。父对象的构造函数始终在子对象之前调用。这可确保对象处于有效状态,并且已扩展另一个类的对象始终可以知道对象所处的状态。

在编译器在您的行为中插入隐式构造函数调用之后,您提供了以下代码。注意super();总是先叫。

public class Redimix extends Concrete{

    Redimix(){
        super();
        System.out.println("r ");
    }

    public static void main(String[] args) {
        new Redimix();
    }

}

class Concrete extends Sand{
    Concrete() { super(); System.out.print("c "); }
    private Concrete(String s) { }
}

abstract class Sand{
    Sand(){
        super();  // invoking the constructor for java.lang.Object
        System.out.print("s ");
    }
}

答案 2 :(得分:0)

在每个构造函数中,也会调用父构造函数。

答案 3 :(得分:0)

在每个构造函数中,第一个语句总是super(),它调用超类构造函数,但Object

除外

答案 4 :(得分:0)

您需要了解constructor chaining。当您调用任何构造函数时,首先调用所有超类构造函数。在构造函数定义中,如果你没有一个编译器将向超类构造函数添加一个无参数调用,如下所示:super();

这是因为,层次结构中的所有类必须在实际类之前构建,因为您的类依赖于它的超类。

这个超类构造函数的类应始终是构造函数定义中的第一个语句,因为它们必须在此相关类之前构建。所以 Object类构造函数始终是第一个被执行的。