哪个先跑?实例变量或超级构造函数的默认值



根据SCJP6(第507页),我发现在超类构造函数完成之前,实例变量被分配了默认值,我在Debugg模式下尝试了一个例子,但我看到超级承包商在实例变量获得默认值之前运行,有人能向我解释吗?

我在有人想尝试时使用的示例:

package courseExercise;
class test {
    test() {
        System.out.println("Super Constructor run");
    }
}
public class Init extends test {
    private Integer i = 6;
    private int j = 8;
    Init(int x) {
        super();
        System.out.println("1-arg const");
    }
    Init() {
        System.out.println("no-arg const");
    }
    static {
        System.out.println("1st static init");
    }
    public static int d = 10;
    {
        System.out.println("1st instance init");
    }
    {
        System.out.println("2nd instance init");
    }
    static {
        System.out.println("2nd static init");
    }
    public static void main(String[] args) {
        new Init();
        new Init(7);
    }
}

初始化顺序在JLS 12.5:中指定

  1. 首先,为新对象分配内存
  2. 然后,对象中的所有实例变量(包括在该类及其所有超类中定义的实例变量)都被初始化为默认值
  3. 最后,调用构造函数

规范的相关部分是:

如果没有足够的空间为对象分配内存,那么类实例的创建将突然完成,并出现OutOfMemoryError否则,新对象中的所有实例变量,包括在超类中声明的实例变量,都将初始化为其默认值(§4.12.5)。

就在返回对新创建对象的引用之前,将处理指示的构造函数,以使用以下过程初始化新对象:

这就是您永远不应该从构造函数调用非final方法的原因之一:该方法可能被子类覆盖,在这种情况下,该方法将在子类有机会设置该方法可能需要的状态之前被调用。考虑这个例子:

public class Super {
  private final int superValue;
  protected Super() {
    superValue = getSuperValue();
  }
  protected int getSuperValue() {
    return 1;
  }
  @Override
  public String toString() {
    return Integer.toString(superValue);
  }
}
public class Sub extends Super {
  private final int superValueOverride;
  public Sub(int value) {
    this.superValueOverride = value;
  }
  @Override
  protected int getSuperValue() {
    return superValueOverride;
  }
  public static void main(String[] args) {
    Super s = new Sub(2);
    System.out.println(s);
  }
} 

看起来s.superValue应该是2,对吧?毕竟,Sub覆盖getSuperValue()以返回superValueOverride的值,该值被初始化为2。但是,该方法在Sub的任何字段初始化(而不是默认值)之前被调用,因此s.superValue实际上是0(superValueOverride的默认值)。

这更奇怪,因为superValueOverridefinal,但它似乎改变了它的值!当Super调用getSuperValue()时,它是0,只有在Super构造函数完成后,它才会分配其最终值2(或传递给构造函数的任何值)。

相关内容

  • 没有找到相关文章

最新更新