Java类变量初始化的顺序是什么? [英] In what order are Java class variables initialised?

查看:81
本文介绍了Java类变量初始化的顺序是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I came across these questions recently, and could not find the answer on StackOverflow;


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

  2. 有些相关问题,可以重新排序变量改变类行为吗?

  3. 为什么?

正如 Meta 我将发布我对这个问题的回答。

As suggested on Meta I will be posting my answer to this question.

推荐答案

在Java中,类变量是在以下订单中初始化:

In Java, class variables are initialised in the following order:


  1. 超类的静态变量

  2. 此类的所有静态变量都设置为默认值

  3. 静态变量和静态初始化块,按声明顺序。

  4. 超类的实例变量

  5. 此类的所有实例变量都设置为默认值

  6. 实例变量和实例级初始化块,按声明顺序

  1. Static variables of your superclasses
  2. All static variables of this class are set to their default values.
  3. Static variables, and static initialisation blocks, in declaration order.
  4. Instance variables of your superclasses
  5. All instance variables of this class are set to their default values.
  6. Instance variables, and instance level initialisation blocks, in declaration order

1& 2只在第一次实例化类时才完成。

1 & 2 are only done the very first time that a class is instantiated.

因此,给出以下代码:

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 ++; }
}

然后我们得到以下输出:

Then we get the following output:

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

从这个输出中我们可以看到字段是按照列表中指定的顺序初始化的。

From this output we can see that the fields are initialised in the order specified in the list.

现在,关于第二个问题,可以重新排序字段来改变类的行为。是的,通过重新排序字段,您可以更改字段的初始化顺序。现在,在所有字段都是独立的特定情况下,这不会影响观察到的行为,但是每当字段不是独立的时,例如在上面的代码中,那么重新排序字段可以改变它们的初始值。

Now, as to the second question, can re-ordering the fields change the class behaviour. Yes, by re-ordering the fields you change the initialisation order of the fields. Now, in the specific case where all of the fields are independent, this won't affect the observed behaviour, however whenever the fields are not independent, for example in the above code, then re-ordering the fields could change their initialised values.

例如,如果三行:

  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

ss2 ss1 会更改值。

原因是此行为在 Java语言规范

这篇关于Java类变量初始化的顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆