javaclassloader的准备阶段和初始化阶段
Preparation stage and initialization stage of java class loader
我无法理解以下各行之间的区别 (http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.2)
A) 准备工作包括将静态字段初始化为默认值。
B) class 的初始化包括对 class.
中声明的静态字段(class 变量)执行初始化程序
是否意味着 'a' 将在 "preparation" 阶段分配默认值,而 'b' 将在 "Initialization" 阶段分配默认值:
static int a;
static int b=2;
"Initializing to default values" 表示字段设置为以下值:
- 布尔值:假
- 整数、长、字节、短:0
- 双精度,浮点数:+0.0
- char: '\u0000'
- 引用类型:null
"Initializing by executing initializers" 意味着现在分配给那些静态字段的表达式被评估并分配给它们。
因此,在 "preparation" 阶段,您的 a
和 b
将被创建并接收值 0
。在"initialization"阶段,b
会收到值2
.
使用有副作用的方法很容易验证这一点。我们不是将简单的“2”分配给 b
,而是调用一个静态方法 returns 值 2
,但它还会在执行此操作之前打印有关变量的信息:
public class SimpleTest {
private static int a;
private static int b = printAAndBReturning2("initializer");
static {
printAAndBReturning2("static initializing block");
}
public static void main(String[] args) {
printAAndBReturning2("main");
}
public static int printAAndBReturning2(String where) {
System.out.printf("In %s a is %d and b is %d%n", where, SimpleTest.a, SimpleTest.b);
return 2;
}
}
输出为:
In initializer a is 0 and b is 0
In static initializing block a is 0 and b is 2
In main a is 0 and b is 2
此演示还用于警告您在初始化阶段使用 运行 的方法。
原始类型的所有字段将自动初始化为默认值。
因为int是0。所以a == 0
。您可以检查默认值 here.
它在非原始类型上有所不同(类)。
所以
Font a;
-> a == null
(如果您尝试使用 a
的方法,您将得到 a is not initialized
。
Font b = new Font("Dialog", 16, Font.BOLD);
-> b == ...
(我想你明白了)。
我无法理解以下各行之间的区别 (http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.2)
A) 准备工作包括将静态字段初始化为默认值。
B) class 的初始化包括对 class.
中声明的静态字段(class 变量)执行初始化程序是否意味着 'a' 将在 "preparation" 阶段分配默认值,而 'b' 将在 "Initialization" 阶段分配默认值:
static int a;
static int b=2;
"Initializing to default values" 表示字段设置为以下值:
- 布尔值:假
- 整数、长、字节、短:0
- 双精度,浮点数:+0.0
- char: '\u0000'
- 引用类型:null
"Initializing by executing initializers" 意味着现在分配给那些静态字段的表达式被评估并分配给它们。
因此,在 "preparation" 阶段,您的 a
和 b
将被创建并接收值 0
。在"initialization"阶段,b
会收到值2
.
使用有副作用的方法很容易验证这一点。我们不是将简单的“2”分配给 b
,而是调用一个静态方法 returns 值 2
,但它还会在执行此操作之前打印有关变量的信息:
public class SimpleTest {
private static int a;
private static int b = printAAndBReturning2("initializer");
static {
printAAndBReturning2("static initializing block");
}
public static void main(String[] args) {
printAAndBReturning2("main");
}
public static int printAAndBReturning2(String where) {
System.out.printf("In %s a is %d and b is %d%n", where, SimpleTest.a, SimpleTest.b);
return 2;
}
}
输出为:
In initializer a is 0 and b is 0 In static initializing block a is 0 and b is 2 In main a is 0 and b is 2
此演示还用于警告您在初始化阶段使用 运行 的方法。
原始类型的所有字段将自动初始化为默认值。
因为int是0。所以a == 0
。您可以检查默认值 here.
它在非原始类型上有所不同(类)。
所以
Font a;
-> a == null
(如果您尝试使用 a
的方法,您将得到 a is not initialized
。
Font b = new Font("Dialog", 16, Font.BOLD);
-> b == ...
(我想你明白了)。