Java超级构造函数执行序列

时间:2013-10-03 01:24:31

标签: java

我一直在学习Java Certification Bates和Sierra的书,并且对第2章构造函数的解释感到难过:

public class Animal {
    String name;

    Animal(String name) {
        super();

        {System.out.println("Hello");} //I put this in myself

        this.name = name;
    }

    Animal() {
        this(makeRandomName());
    }


    static String makeRandomName() {
        int x = (int) (Math.random() * 5);
        String name = new String[] {"Fluffy", "Fido",
        "Rover", "Spike",
        "Gigi"}[x];
        return name;
    }

    public static void main (String [] args) {
        Animal a = new Animal();
        System.out.println(a.name);
        Animal b = new Animal("Zeus");
        System.out.println(b.name);
    }
}

以下是Bates和Sierra的书:

  

请注意,makeRandomName()方法标记为static!那是   因为你无法调用实例(换句话说,非静态)   方法(或访问实例变量)直到super之后   构造函数已运行。并且因为将调用超级构造函数   从第3行的构造函数,而不是第7行的构造函数,   第8行只能使用静态方法来生成名称。

我做了一个实验,我在重载的构造函数中插入了一个超级调用,结果是:

 Hello 
 Rover
 Hello
 Zeus

现在从这些结果来看,似乎重载的构造函数和超级构造函数在静态方法之前执行,因为Hello在Zeus和Rover之前打印。那么,为什么需要静态变量?

我错过了什么?

3 个答案:

答案 0 :(得分:3)

方法makeRandomName()super之前被称为 。您的print语句仅表明您正在使用其他构造函数执行后生成的值。要查看差异,请将打印语句直接插入makeRandomName()

答案 1 :(得分:1)

构造函数中的super()调用不会改变任何内容。无论如何,它本可以由编译器隐式添加。

至于执行

Animal a = new Animal();

调用空构造函数,调用

this(makeRandomName());
执行

makeRandomName()并返回String,用于调用接受String的1-arg构造函数。打印"Hello"并分配字段name。构造函数返回。随机名称被打印出来。

然后使用

调用1-arg构造函数
Animal b = new Animal("Zeus");

打印"Hello",设置字段,返回。然后main打印"Zeus"


  

那么,为什么需要静态变量?

如果您从static方法中删除了makeRandomName(),则以下内容无法编译

Main() {
    this(makeRandomName());
}

该对象尚未初始化,因此您无法在其上调用方法。

答案 2 :(得分:1)

  

似乎重载的构造函数和超级构造函数在静态方法之前执行,因为Hello在Zeus和Rover之前打印。

您的代码中没有任何内容可以证明这一点。将跟踪放入静态方法,您将看到真正的执行顺序。

  

那么,为什么需要静态变量?

没有。您发布的代码中没有静态变量。有一个静态方法。尝试将其设置为非静态,您将从错误中看到它不能从this()内部调用,除非它是静态的。