静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)
一、单类例子
public class Static {
public static int k = 0;
public static Static s1 = new Static("t1");
public static Static s2 = new Static("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
//非静态代码块
{
print("构造块");
}
//静态代码块
static
{
print("静态块");
}
//构造方法
public Static(String str){
System.out.println((++k)+":"+str);
++i;++n;
}
public static int print(String str){
System.out.println((++k)+":"+str);
++n;
return ++i;
}
public static void main(String[] args) {
}
输出结果:
1:j
2:构造块
3:t1
4:j
5:构造块
6:t2
7:i
8:静态块
注解:
首先执行 public static Static s1 = new Static("t1");因为他是出现最早的静态语句,new Static("t1")之后,执行Static类中的public int j = print("j")这一句,可是为什么不执行静态代码块呢?
静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次 ,而且给变量或者代码块添加static关键字后,Static对象就不再拥有该属性了,被添加static关键字的属性会统一交给Static类去管理,即多个Static对象只会对应一个被static修饰的属性
二、多类继承例子
class Parent{
static String name = "hello";
{
System.out.println("3 parent block");
}
static {
System.out.println("1 parent static block");
}
public Parent(){
System.out.println("4 parent constructor");
}
}
class Child extends Parent{
static String childName = "hello";
{
System.out.println("5 child block");
}
static {
System.out.println("2 child static block");
}
public Child(){
System.out.println("6 child constructor");
}
}
public class StaticIniBlockOrderTest {
public static void main(String[] args) {
new Child();
}
}
结果:
1 parent static block
2 child static block
3 parent block
4 parent constructor
5 child block
6 child constructor
2. 顺序:
1)执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容;
2)当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构 造方法;
3)父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。
总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
而且子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。