让我们看一下下面的Java代码段。
package trickyjava;
class A
{
public A(String s)
{
System.out.println(s);
}
}
final class B extends A
{
public B()
{
super(method()); // Calling the following method first.
}
private static String method()
{
return "method invoked";
}
}
final public class Main
{
public static void main(String[] args)
{
B b = new B();
}
}
按照约定,Java中的super()构造函数必须是相关构造函数主体中的第一条语句。在上面的代码中,我们在super()构造函数参数列表本身中调用static方法super(method());。。
这意味着在构造函数B()中对super的调用中,在进行对super的调用之前,将调用一个方法!编译器应禁止这样做,但效果很好。这在某种程度上等同于以下语句。
String s = method();
super(s);
但是,这是非法的,导致出现编译时错误,表明“对super的调用必须是构造函数中的第一条语句”。为什么?以及为什么它等同于super(method()); 是有效的,编译器不再抱怨了吗?
这里的关键是static
修饰符。静态方法绑定到类,实例方法(普通方法)绑定到对象(类实例)。构造函数从一个类初始化一个对象,因此该类必须已经完全加载。因此,调用静态方法作为构造函数的一部分是没有问题的。
加载类和创建对象的事件顺序如下:
(简体*)
到对象构造函数被调用时,静态方法和变量可用。
将类及其static
成员视为该类对象的蓝图。您只能在蓝图已经存在的情况下创建对象。
构造函数也称为初始化程序。如果从构造函数中抛出异常并打印堆栈跟踪,您会注意到它<init>
在堆栈框架中被调用。实例方法只能在构造对象之后调用。不能将实例方法用作super(...)
构造函数中调用的参数。
如果创建相同类的多个对象,则步骤1和2仅发生一次。
(为清晰起见,省略了静态初始化程序和实例初始化程序)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句