静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)
一、单类例子
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关键子来调用父类带参数的构造方法,否则编译不能通过。