为什么Java静态变量没有更新?

时间:2018-07-08 07:24:05

标签: java static

我有一个名为Color的类,其中有三个静态Object(使用相同的类本身实例化)和一个int类型(称为i)变量。当我运行类时,“ i”变量在构造函数中为增量,但未持久存储在内存中,请在下面的代码中对此解释

brtrue.s

结果如下:

myObj

2 个答案:

答案 0 :(得分:7)

在加载和链接一个类时,其static字段都将初始化为它们的默认值。一旦完成,将按照静态字段初始化程序在文件中出现的顺序执行它们,从而完成类的初始化。所有这些发生在该类中定义的任何代码执行之前。所以这里发生的是:

  1. REDGREENBLUEi初始化为其默认值(null字段为Colori)。请注意,这与任何初始化程序无关。
  2. 执行字段REDRED = new Color())的初始化程序。副作用是,i增加到1。
  3. 执行字段BLUE的初始化程序,并将i递增到2。
  4. 执行字段GREEN的初始化程序,并将i递增到3。
  5. 执行static字段i的初始化程序,并为i分配值0。
  6. main()方法开始执行,并产生与i开始执行时main()为0一致的结果。

您可以在Chapter 12 of the Java Language Specification (JLS)Chapter 5 of the Java Virtual Machine Specification中阅读所有详细信息。

只需将i的声明移到Color字段的前面,即可获得所需的输出:

 static int i=0;
 public static  Color RED = new Color();
 public static final Color BLUE = new Color();
 public static final Color GREEN = new Color();

然后输出将是:

  

在这里增加“ i” 1
  在此处递增“ i” 2
  在这里递增“ i” 3
  “ i”变量在此处未递增,仍显示为“ 0”,“ i”为:3
  在此处增加“ i” 4
  4

请注意,final修饰符在这里对初始化顺序没有影响,因为根据JLS中该术语的定义,GREENBLUE不是“常数变量”。 常量变量(不幸的单词对)是原始变量或String变量,都声明为final并初始化为常量表达式。在这种情况下,new Color()不是常数表达式,Color不是常数变量的合适类型。例如,参见§4.12.4 of the JLS

答案 1 :(得分:0)

类初始化从上到下进行。当初始化Color时,我们创建了一个新的Color。为了创建一个新的Color,我们还必须初始化Color。这就是所谓的递归初始化,而系统所做的只是忽略递归初始化并执行new Color()。此类初始化程序按以下顺序从上到下执行

  1. public static Color RED = new Color();会将静态变量i设置为1。

  2. public static final Color BLUE = new Color();将静态变量i增加到2

  3. public static final Color GREEN = new Color();将静态变量i增加到3

  4. static int i=0;会将静态变量i重置为零。

现在在主线程运行时。它将看到静态变量为0,然后递增为1。

作为反例,尝试将static int i=0替换为static Integer i=new Integer(0).。这将抛出NullPointerException。这是因为在类初始化时,public static Color RED = new Color();执行时,它将i视为null,因为那时i尚未初始化,导致NullPointerException