我一直在学习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之前打印。那么,为什么需要静态变量?
我错过了什么?
答案 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()
内部调用,除非它是静态的。