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

Moh*_*Ali 4 java static

我有一个名为Color的类,其中有三个静态对象(使用相同的类本身实例化)和一个int类型(称为i)变量.当我运行类时,'i'变量在构造函数中是递增的,但它不会在内存中持久存在,请在下面解释这个代码

package test;
public class Color
{
     public static  Color RED = new Color();
     public static final Color BLUE = new Color();
     public static final Color GREEN = new Color();
     static int i=0;

     Color(){
         System.out.println("Incrementing 'i'  here  "+(++i));
     }

     public static void main(String[] args) {
         System.out.println("The 'i' variable is not incremented here, it still shows '0' ,  'i' is: "+ Color.i );  // line 14 
        Color x = new Color();
        System.out.println(x.i);
    }
}
Run Code Online (Sandbox Code Playgroud)

出局如下:

Incrementing 'i'  here  1
Incrementing 'i'  here  2
Incrementing 'i'  here  3
The 'i' variable is not incremented here, it still shows '0' ,  'i' is: 0
Incrementing 'i'  here  1
1
Run Code Online (Sandbox Code Playgroud)

Ted*_*opp 7

加载并链接类时,其static字段全部初始化为其默认值.完成后,静态字段初始化程序按它们在文件中出现的顺序执行,从而完成类的初始化.所有这些都发生在该类中定义的任何代码执行之前.那么这里发生的是:

  1. RED,GREEN,BLUE,和i被初始化为默认值(null用于Color场和0 i).请注意,这与任何初始值设定项无关.
  2. field RED(RED = new Color())的初始化程序执行.作为副作用,i增加到1.
  3. 字段的初始化程序BLUE执行并i递增为2.
  4. 字段的初始化程序GREEN执行并i增加到3.
  5. static字段的初始化程序i执行并被i赋值为0.
  6. main()方法imain()开始执行时执行并产生与0 一致的结果.

你可以在阅读这一切的血淋淋的细节Java语言规范(JLS)第12章Java虚拟机规范的第5章.

只需将声明移到字段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();
Run Code Online (Sandbox Code Playgroud)

然后输出将是:

增加'i'在这里1
增加'i'在这里2
增加'i'在这里
3'i'变量在这里没有增加,它仍然显示'0','i'是:3
增加'i'这里4
4

需要注意的是final修饰符这里是因为初始化的顺序没有任何影响GREENBLUE是不是"常变量"根据在JLS该术语的定义.甲常量变量(字的一个不幸的配对)是一个原始或String既声明的变量final并初始化为一常量表达式.在这种情况下,new Color()不是常量表达式,Color并且不是常量变量的合适类型.例如,参见JLS的§4.12.4.