静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)

一、单类例子

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关键子来调用父类带参数的构造方法,否则编译不能通过。