import java.util.Random;
class test1{
public static final int x = 6/2;
static {
System.out.println("test1 static block");
}
}
class test2{
public static final int x = new Random().nextInt();
static {
System.out.println("test2 static block");
}
}
public class Demo {
public static void main(String[] args) {
System.out.println("-------打印test1x---------");
System.out.println(test1.x);
System.out.println("-------打印test2x---------");
System.out.println(test2.x);
}
}
运行结果:
-------打印test1x---------
3
-------打印test2x---------
test2 static block
1398792214
为什么第二个打印静态代码块第一个没打印呢?原因是这样的test1里的x是编译时的常量不会对类进行初始化而test2中不是编译时常量 会对类进行初始化 所谓编译时常量就是指编译时就能确定它的值
当类初始化时 首先去初始化他的直接父类或间接父类 父类初始化完了 然后在初始化 但不会初始化实现的接口 该类本身
当初始化一个接口的时候不回去初始化它的父接口
package com.cn;
class Parent {
public static final int a = 3;
static {
System.out.println("parent static block");
}
}
class Child extends Parent{
public static final int b = 4;
static {
System.out.println("child static block");
}
}
public class J2SETest{
//这个静态代码会首先被执行
static {
System.out.println("J2SETest static block");
}
public static void main(String[] args) {
//执行这句话时是不会对Parent进行初始化的 因为只是对变量进行声明 并没有产生对象 只有 对类进行主动调用时才会被初始化
Parent parent ;
//这句话会对Parent进行初始化
parent = new Parent();
System.out.println(parent.a);
//这句话会首先去初始化父类 但父类在new Parent()这条语句时已经被初始化了
//所以不用重新初始化父类 而是直接初始化Child 但这只限于该Parent只被一个类加载器加载 如果被另一个加载器加载 会被重新初始化
//下面这条语句也是对Chid的主动调用 但b的值是编译时常量 在编译时它的值都已经确定了 所以Child里的静态代码块是不会被执行的
System.out.println(Child.b);
//现在大家可以猜一猜它的运行结果
//预测运行结果是:
//1. J2SETest static block
//2. parent static block
//3. 3
//4. 4
}
}