我有一个名为Color的类,其中有三个静态Object(使用相同的类本身实例化)和一个int类型(称为i)变量。当我运行类时,“ i”变量在构造函数中为增量,但未持久存储在内存中,请在下面的代码中对此解释
brtrue.s
结果如下:
myObj
答案 0 :(得分:7)
在加载和链接一个类时,其static
字段都将初始化为它们的默认值。一旦完成,将按照静态字段初始化程序在文件中出现的顺序执行它们,从而完成类的初始化。所有这些发生在该类中定义的任何代码执行之前。所以这里发生的是:
RED
,GREEN
,BLUE
和i
初始化为其默认值(null
字段为Color
, i
)。请注意,这与任何初始化程序无关。RED
(RED = new Color()
)的初始化程序。副作用是,i
增加到1。BLUE
的初始化程序,并将i
递增到2。GREEN
的初始化程序,并将i
递增到3。static
字段i
的初始化程序,并为i
分配值0。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中该术语的定义,GREEN
和BLUE
不是“常数变量”。 常量变量(不幸的单词对)是原始变量或String
变量,都声明为final
并初始化为常量表达式。在这种情况下,new Color()
不是常数表达式,Color
不是常数变量的合适类型。例如,参见§4.12.4 of the JLS。
答案 1 :(得分:0)
类初始化从上到下进行。当初始化Color时,我们创建了一个新的Color。为了创建一个新的Color,我们还必须初始化Color。这就是所谓的递归初始化,而系统所做的只是忽略递归初始化并执行new Color()
。此类初始化程序按以下顺序从上到下执行
public static Color RED = new Color();
会将静态变量i设置为1。
public static final Color BLUE = new Color();
将静态变量i增加到2
public static final Color GREEN = new Color();
将静态变量i增加到3
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