Javaでのフリーブロックの実行順序

4277 ワード

  • javaのフリーブロックは、静的フリーブロックと非静的フリーブロックに分けられる.
  • 非静的フリーブロックの実行時間は、コンストラクション関数を実行する前である.
  • 静的フリーブロックの実行時間は、classファイルのロード時に実行されます.
  • 非静的フリーブロックは、1つのオブジェクトを初期化する限り複数回実行できますが、静的フリーブロックはクラスのマウント時に1回のみ実行され、一般的にクラスの静的変数の値を初期化するために使用されます.
  • は、オブジェクトを初期化するたびに、非静的ブロックの実行をもたらす.
  • 継承に関連する場合、まず親の非静的ブロックを実行し、次に親の構造関数、次に自分の自由ブロック、最後に自分の構造関数を実行する.
  • 静的ブロックの実行タイミングは、classファイルがロードされたときにclassファイルが1回しかロードされないため、静的ブロックは1回しか実行されず、後でこのクラスを使用する場合、静的ブロックは実行されません. 
  • 静的ブロックの実行タイミングはclassマウント後の初期化段階である.ClassLoaderのloadclassを使用してクラスを初期化せずにマウントする場合、静的ブロックの実行はトリガーされません.Classを採用したforname(String)は、デフォルトのinitializeをtrueとした場合、つまり初期化されます.forname(String name,boolean initialize,ClassLoader loader)を使用してinitializeをfalseに設定した場合、静的ブロックは実行されません.
  • classマウントを実行した初期化フェーズには、クラス変数の初期化文と静的フリーブロック文である実行方法が含まれます.この方法はjavaのコンパイラが情報を収集して生成し,表示できない呼び出しである.

  • 次に例を挙げて説明します.
     
      
    father.java

    public class father {

        static{//
           System.out.println("father'sSTATIC free block running");
        }

        {//
     System.out.println("father'sfree block running");
        }

        public father(){

           System.out.println("father'sconstructor running");

        }
    }


    サブクラス
     
      
    son.java
    public class son extends father{
        static{//
           System.out.println("son'sSTATIC free block running");
        }

        {//
           System.out.println("son's freeblock running");
        }

        public son() {
           // TODO Auto-generated constructor stub
           System.out.println("son'sconstructor running");
        }
    }


    主関数が存在するクラス
     
      
    test.java

    public class test{

          public static void main(String[] args) {

           Class f;

           try {

               System.out.println("--------beforeload father--------");

               f=Class.forName("freeblock.father");

               System.out.println("--------afterload father---------");        

               System.out.println("--------beforeinitial father object--------");

               f.newInstance();

               System.out.println("--------afterinitial father object--------");

           } catch (ClassNotFoundException e) {

               e.printStackTrace();

           } catch (InstantiationException e) {
               e.printStackTrace();

           } catch (IllegalAccessException e) {

               e.printStackTrace();
           }     
           Class s;

           try {

               System.out.println("-------beforeload son--------");

               s=Class.forName("freeblock.son");

               System.out.println("--------afterload son-------");

               System.out.println("--------beforeinitial son object----------");

               s.newInstance();

               System.out.println("--------afterinitial son object-----------");

           } catch (ClassNotFoundException e) {
               e.printStackTrace();
           } catch (InstantiationException e) {
               e.printStackTrace();
           } catch (IllegalAccessException e) {
               e.printStackTrace();
           }
        }
    }


    実行結果:
    --------before loadfather--------
    father's STATIC free blockrunning
    --------after loadfather---------
    --------before initial fatherobject--------
    father's free block running
    father's constructor running
    --------after initial fatherobject--------
    -------before load son--------
    son's STATIC free block running
    --------after load son-------
    --------before initial sonobject----------
    father's free block running
    father's constructor running
    son's free block running
    son's constructor running
    --------after initial son object-----------