初始化:给类的静态变量赋值(在链接阶段会赋默认值,主动使用这个类,才会初始化)
在给静态变量赋值时,是按照循序赋值的。并不是先给静态代码块赋值。如果静态字段在静态代码块 前,会先初始化静态字段
- 当子类的成员变量可以在编译期确定时,jvm是不会初始化这个类(即不是主动引用这个类)。会将 这个常量加入 所使用该常量所在类的常量池中
public class Test3 {
public static void main(String[] args) {
System.out.println(Child3.childVariate);
}
}
// 父类
class Parent3{
public static int parentVariate = 2;
static {
System.out.println("parent static block");
}
}
// 子类
class Child3 extends Parent3{
public static final int childVariate = 1;
static {
System.out.println("child static block");
}
}
``
结果:1
理解:childVariate是可以在编译时确定的常量。这里jvm实际上只初始化了Test3这个类,并将childVariable
加入了Test3所在的类
2 .使用一个类的静态变量时,会初始化这个类。如果这个类有父类,也会初始化其父类
public class Test1 {
public static void main(String[] args) {
System.out.println(Child.childVariate);
}
}
class Parent{
public static int parentVariate = 2;
static {
System.out.println("parent static block");
}
}
class Child extends Parent{
public static int childVariate = 1;
static {
System.out.println("child static block");
}
}
结果:
parent static block
child static block
1
理解:
1.这里和上面唯一的不同就是childVariable没加final修饰。在Test1类中 System.out.println(Child.childVariate);
就是主动使用这个类(使用类的静态变量)。因为这个类有父类,也会初始化其父类(也是主动使用这个类)
jvm就会初始化Parent,和Child这两个类。
初始化循序:parentVariable赋值为2
执行静态代码块:
输出parent static block
childVariable赋值为1
执行静态代码块:
输出child static block
在在test类输出 1
3.综合来看类成员初始化
public class Test2{
public static void main(String[] args) {
new Parent();
System.out.println(Child.childVariate);
}
}
class Parent{
public Parent() {
System.out.println("parent constructor");
}
public static int parentVariate = 1;
static {
System.out.println("parent static block");
}
}
class Child extends Parent{
public Child() {
System.out.println("child constructor");
}
public static int childVariate = 1;
static {
System.out.println("child static block");
}
}
结果:
parent static block
parent constructor
child static block
1
理解:
先加载主类:Test2{} (因为有main方法,这是jvm的入口)
1):new Parent();
这个代码,就是主动使用Paren类。jvm虚拟机会初始化Parent{}这个类
A:先初始化parentVariate为1
B:执行静态代码块,
输出parent static block
2): Parent{} 类初始化好了,就执行new语句
输出:parent constructor
3):System.out.println(Child.childVariate);
这个代码,就是主动使用Child类。jvm虚拟机会初始化Child{}这个类
A:先初始化childVariate为1
B:执行静态代码块,
输出childe static block