staticブロックはいったいいつ実行しますか?


回転:http://www.iteye.com/topic/11003
 
「java深さ冒険」という本は、「類積載」を説明する章で、以下の例を挙げています。
public interface Assembly{
    public void start();;
}

public class Word implements Assembly{
    static{
        System.out.println("Word static initialization!");;
    }    

    public  void start();{
        System.out.prinlnt("Word starts");;
    }
}

public class Office{
    public static void main(String args[]); throws Exception{
        Office off = new Office();;
        System.out.println("      ");;
        Class c = Class.forName(args[0],true,off.getClass();.getClassLoader(););;
        System.out.println("       ");;
        Object o = c.newInstance();;
        Object o2= c.newInstance();;
   }
}
 java Office Wordを実行した結果、「Loaded Office」「カテゴリロード準備」「Loaded Accembly」「Loaded Word」「Word static initialization」「カテゴリ準備実体化」のようになりました。しかし、Office.javaのクラス.forName(args[0],true,off.get Class().get Class Loader()の中のtrueをfalseに変更し、java Office Wordを実行した結果、「Loaded Office」「カテゴリロード準備」「Loaded Accement bledy」「World」「Worlect」「Worlititition」と表示されました。
 
二回の赤字部分の順序が逆であり、staticブロックの実行順序が異なることは明らかである。この本の著者は原因を提出しました。
参照
「過去に多くのjava書で静的初期化(static initializion block)に言及されています。は、静的初期化ブロックはクラスの最初のロード時にのみ呼び出されると言われていますが、上の出力はクラスがロードされていても、その静的初期化ブロックは呼び出されていません。newInstanceメソッドが初めて起動された時に、静的な初期化ブロックは本格的に呼び出されます。静的な初期化ブロックはクラスで初めてエンティティに呼び出されるべきです。一度だけ呼び出されます。」
実は、この本の作者の上述の説明は間違っています。一つの実験を通して,誤りのありかがわかる。
public class TestA{
    static{
       System.out.println("Static block executed!");;
    }    
}

public class Test{
    public static void main(String args[]);{
       Test test = new Test();;
       Class.forName("TestA",true,test.getClass();.getClassLoader(););;
   }
}
 運行してみてください。きっと見られると思います。「Static block executed!」の出力です。これと
参照
代わりに、newInstanceメソッドが初めて起動されたときに、静的初期化ブロックが本格的に起動される。
の言い方が矛盾しています実はこのようなことがあると思います。一つの種類の運行は、JVMが以下のいくつかのことができます。初期化段階で行うことは、静的変数の初期化や静的方法の実行などです。ですから、Class.forName(args[0],true,off.get Class().get Class Loader;のtrueがfalseになった時、JVMがもうロードクラスをしないで、initialの仕事をするということです。このように、initialの仕事をnewInstanceの時に延期します。したがって、staticブロックの絶対は何でもないです。クラスが初めて実体化された時に一回だけ呼び出されます。