Java类变量的初始化顺序是什么?

7

我最近遇到了这些问题,在StackOverflow上找不到答案;

  1. Java类变量初始化的顺序是什么?
  2. 还有一个相关的问题,重新排列变量是否会更改类的行为?
  3. 为什么?

根据Meta的建议,我将发布这个问题的答案。

1个回答

8

在Java中,类变量的初始化顺序如下:

  1. 超类的静态变量
  2. 该类所有静态变量被设置为它们的默认值。
  3. 按照声明顺序排列的静态变量和静态初始化块。
  4. 超类的实例变量
  5. 该类所有实例变量被设置为它们的默认值。
  6. 按照声明顺序排列的实例变量和实例级别初始化块

1和2只在类第一次实例化时执行。

因此,给定以下代码:

class Test
  extends TestSuper
{
  final int ti1;
  final int ti2 = counter ++;
  { ti1 = counter ++; }
  static final int ts1;
  static final int ts2 = counter ++;
  static { ts1 = counter ++; }

  public static void main(String[] argv) {
    Test test1 = new Test();
    printTest(test1);
    Test test2 = new Test();
    printTest(test2);
  }
  private static void printTest(Test test) {
    System.out.print("ss2 = " + test.ss2);
    System.out.print(", ss1 = " + test.ss1);
    System.out.print(", ts2 = " + test.ts2);
    System.out.println(", ts1 = " + test.ts1);
    System.out.print("si2 = " + test.si2);
    System.out.print(", si1 = " + test.si1);
    System.out.print(", ti2 = " + test.ti2);
    System.out.println(", ti1 = " + test.ti1);
    System.out.println("counter = " + test.counter);
  }
}

class TestSuper
{
  static int counter = 0;
  final int si1;
  final int si2 = counter ++;
  { si1 = counter ++; }
  static final int ss1;
  static final int ss2 = counter ++;
  static { ss1 = counter ++; }
}

然后我们得到以下输出:
ss2 = 0, ss1 = 1, ts2 = 2, ts1 = 3
si2 = 4, si1 = 5, ti2 = 6, ti1 = 7
counter = 8
ss2 = 0, ss1 = 1, ts2 = 2, ts1 = 3
si2 = 8, si1 = 9, ti2 = 10, ti1 = 11
counter = 12

从这个输出结果我们可以看到,字段按照列表中指定的顺序进行初始化。
现在,对于第二个问题,重新排序字段是否会改变类的行为。是的,通过重新排序字段,您可以改变字段的初始化顺序。现在,在所有字段都是独立的特定情况下,这不会影响观察到的行为,但是每当字段不独立时,例如在上面的代码中,重新排序字段可能会改变它们的初始化值。
例如,如果以下三行:
  static final int ss1;
  static final int ss2 = counter ++;
  static { ss1 = counter ++; }

被改为:

  static final int ss1;
  static { ss1 = counter ++; }
  static final int ss2 = counter ++;

然后输出将会改变为:
ss2 = 1, ss1 = 0, ts2 = 2, ts1 = 3
si2 = 4, si1 = 5, ti2 = 6, ti1 = 7
counter = 8

这意味着,ss2ss1的值将会改变。 原因在于这种行为被规定在Java语言规范中。

1
我认为当所有字段都是独立的情况只是一个特例,而不是反过来。 - witzar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接