执行顺序:
父类静态代码块> 子类静态代码块 > 父类构造代码块 > 父类构造函数 >子类构造代码块>
子类构造函数 > 普通代码块
1、静态代码块–在java类中使用static{}包裹的代码
public class testA{
static{
System.out.println("hello");
}
}
- 静态代码块在类被加载时运行,只运行一次,优先于各种代码块和构造函数。如果一个类中有多个静态代码块,按照书写顺序依次执行。
- 作用:有些代码需要在项目启动时就执行,如加载配置文件等资源,这时就需要静态代码块。
- 静态代码块不能存在于任何方法体中。静态代码块在类加载时就要运行,假如放在普通方法中,需要先加载类,然后newchu实例化对象,通过对象运行这个方法。假如放入静态方法,在类加载时静态方法也被加载了,但需要通过类名或对象名才能访问,是被动运行的。
- 静态代码块不能访问普通变量。
2、构造代码块–在java类中使用{}声明的代码
public class testA{
{
System.out.println("hello");
}
}
- 构造代码块在对象被创建时调用,每次创建对象都会调用一次,优先于构造函数执行。如果不实例化对象,构造代码块是不会执行的。
- 作用:只要创建一个对象,构造代码块都会执行一次,可以用来统计创建对象的次数。(构造函数不一定每个对象建立时都执行,假如有多个构造函数,传入的参数不同,执行的构造函数也不同)
3、构造函数
- 构造函数不能直接被调用,必须通过new 运算符才会在创建对象时被自动调用
- 作用:创建对象时进行初始化
4、例题
public class HelloA {
public HelloA(){
System.out.println("HelloA");
}
{
System.out.println("I'm A class");
}
static {
System.out.println("static A");
}
}
public class HelloB extends HelloA {
public HelloB(){
System.out.println("HelloB");
}
{
System.out.println("I'm B class");
}
static {
System.out.println("static B");
}
public static void main(String[] args) {
new HelloB();
}
}
输出:
static A
static B
I'm A class
HelloA
I'm B class
HelloB
public class B
{
public static B t1 = new B();
public static B t2 = new B();
{
System.out.println("构造块");
}
static{
System.out.println("静态块");
}
public static void main(String[] args){
B t =new B();
}
}
输出:
构造块
构造块
静态块
构造块
(1)JVM加载B.class,对所有的静态成员进行声明,t1 和 t2被初始化为默认值,为null,接着对静态变量t1,t2进行初始化,执行构造代码块(输出“构造块”,2次),此时JVM认为是第二次加载B.class,所以不执行静态代码块;
(2)静态变量初始化完成后,执行静态代码块(输出“静态块”);
(3)接着执行main方法,执行构造块(输出“构造块”。)