ホームページ >Java >&#&チュートリアル >Java オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?

Java オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?

王林
王林転載
2023-05-10 09:52:081117ブラウズ

    コード読み込みの優先順位

    静的コード ブロック、静的メンバー変数 -> 非静的コード ブロック、非静的メンバー変数 -> new 他のオブジェクトが対応するオブジェクト構築メソッドを呼び出します (ローカル オブジェクトのメソッドに加えて構築メソッドを含む) -> 新しいローカル オブジェクトが構築メソッドを呼び出します。

    Note: オブジェクトが新しい場合、オブジェクト内には静的コード ブロックと非静的コード ブロックが存在します。オブジェクトが新しくなるたびに、非静的コード ブロックはただし、静的コード ブロックは 1 回だけ実行され、新しいオブジェクトは再度実行されません。 】

    構築メソッドの実行順序

    親クラスの静的コードブロック(静的変数>静的ブロック)>サブクラスの静的コードブロック>親クラスの構築コードブロック、構築メソッド>構築コードブロックとサブクラスの構築メソッド

    さまざまなコード ブロックの定義

    静的コード ブロック

    class Demo{ static { //静态代码块...... } }

    特徴: 1. Java 静的コード ブロック コードはクラスの作成時に実行されます。は JVM にロードされ、一度だけ実行されます 2. 静的ブロックは、クラス属性の初期化や一部のグローバル初期化作業によく使用されます 3. 静的ブロックは、さまざまなコード ブロックやコンストラクターよりも優先されます クラスに複数の静的コードがある場合4. 静的コード ブロックは、メソッド本体を除くクラス内の任意の場所に定義できます [ここでのメソッド本体は任意のメソッド本体です] 5. 静的コード ブロックはアクセスできません

    静的コード ブロックを詳しく紹介します

    静的コード ブロック: Java で static キーワードを使用して宣言されたコード ブロック。静的ブロックは、クラスの初期化とクラスのプロパティの初期化に使用されます。各静的コード ブロックは 1 回だけ実行されます。

    JVM はクラスのロード時に静的コード ブロックを実行するため、静的コード ブロックは main メソッドの前に実行されます。クラスに複数の静的コード ブロックが含まれている場合、最初に定義されたコードが最初に実行され、その後に定義されたコードが実行されます。 [注: 1 静的コード ブロックはメソッド本体に存在できません。 2 静的コード ブロックは、静的インスタンス変数およびインスタンス メソッドに直接アクセスできず、クラスのインスタンス オブジェクトを通じてアクセスする必要があります。 】 インスタンスコードブロック インスタンスコードブロックは、コンストラクション初期化ブロック、コンストラクションコードブロック、初期化ブロックとも呼ばれます。

    class Demo{ { //实例代码块...... } }

    機能:

    • #1. 構築コード ブロックはオブジェクトの作成時に呼び出され、オブジェクトが作成されるたびに 1 回呼び出されます。が作成されます

    • 2. コンストラクション コード ブロックは、コンストラクター関数の実行よりも優先されます。同時に、コンストラクション コード ブロックの実行はコンストラクター関数に依存します。

    • 3. 構築コード ブロックは、クラスで定義されたクラスで実行されます

    部分コード ブロック

    部分コード ブロックは、通常のコード ブロック、メソッド コード ブロックとも呼ばれます

    class Demo{ public void test(){ { //局部代码块...... } } }

    特徴: 1. 通常のコード ブロックはメソッド本体で定義されます。2. 通常のコード ブロックとインスタンス コード ブロックの形式は次のとおりです。 {} と同じです。 3. 通常のコード ブロックと構築されたコード ブロックの唯一の直接的な違いは、構築されたコード ブロックが Defined クラスにあるのに対し、通常のコード ブロックはメソッド本体で定義されることです。 4. ライフ サイクルを制限できます。変数の数を減らし、早期に解放して、メモリ使用率を向上させます。

    #各コード ブロックの実行順序を確認します

    コード例は次のとおりです:

    class Init {
        public Init() {
            System.out.println("无参构造器");
        }
        public Init(int a) {
            System.out.println("有参构造器");
        }
        {
            System.out.println("实例代码块1");
        }
        {
            System.out.println("实例代码块2");
        }
        {
            System.out.println("实例代码块3");
        }
        static {
            System.out.println("静态初始化块1");
        }
     
        static {
            System.out.println("静态初始化块2");
        }
    
        public void method(){
        	{
        		System.out.println("普通初始化块");
        	}
        }
    }

    テスト コードは次のとおりです。

    class Demo {
        public static void main(String[] args) {
            Init init1 = new Init();
            init1.method();
            System.out.println("------------");
            Init init2 = new Init();
            init2.method();
            //多打印几个对象的目的是:方便看出Static静态代码块 是否只执行一次!!!
            System.out.println("------------");
            Init init3 = new Init();
            init3.method();
        }
    }

    実行結果は次のとおりです。

    Java オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?

    ##結論:

    実行順序は: 静的コード ブロック > インスタンス コード ブロック > コンストラクター > 通常のコード ブロック 、

    および静的コード ブロックは、クラスがロードされるときに呼び出され、一度だけ呼び出されます (クラスのロード時に実行されます)。

    #それでは、クラスはいつロードされるのでしょうか?

    #- オブジェクト インスタンス (新規) を作成する場合
    - サブクラスのオブジェクト インスタンスを作成する場合、親クラスも読み込まれます

    - クラスの静的メンバー (静的プロパティ、静的メソッド) を使用する場合)


    継承関係における各コード ブロックの実行順序を確認します

    継承関係の例は
    Three——> Two——> One

    ,

    コードは次のとおりです。

    class One {
        public One() {
            System.out.println("One构造器");
        }
     
        {
            System.out.println("One实例化块");
        }
     
        static {
            System.out.println("One静态代码块");
     
        }
     
    }
    class Two extends One {
     
        public Two() {
            System.out.println("Two构造器");
        }
     
        {
            System.out.println("Two实例化块");
        }
     
        static {
            System.out.println("Two静态代码块");
        }
     
    }
     
    class Three extends Two {
     
        public Three() {
            System.out.println("Three构造器");
        }
     
        {
            System.out.println("Three实例化块");
        }
        static {
            System.out.println("Three静态代码块");
        }
     
    }
    //测试代码 如下:
    public class Demo {
        public static void main(String[] args) {
            Three three = new Three();
            System.out.println("-----");
            Three three1 = new Three(); //重复执行的目的是为了 验证static是否只执行一次
            System.out.println("-----");
            Two three2 = new Three();   //验证 多态的情况下 用后面的类进行初始化 结果和上面一样
        }
    }

    実行結果によると、次のことがわかります。複数のクラス、コンストラクターの継承には初期化ブロックと静的初期化ブロックがあることを確認します。実際の実行順序は次のとおりです。親クラス A の静的ブロック、親クラス B の静的ブロック、最後にサブクラスの静的ブロックを実行します。次に、親クラス A のインスタンス コード ブロックとコンストラクターを実行し、次にクラス B のインスタンス コード ブロックとコンストラクターを実行し、最後にサブクラス C のインスタンス コード ブロックとコンストラクターを実行します [注: ここでの ABC は One、Two、Three に対応します] Java オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?

    結論:

    複数のクラスの継承における初期化ブロック、静的初期化ブロック、およびコンストラクターの実行順序は次のとおりです。

    父类静态块——>子类静态块——>父类实例代码块——>父类构造器——>子类实例代码块——>子类构造器 ——>(如果有局部代码块, 再正常执行即可, 这里就没必要进行测试了)

    通过字节码深究实例代码块优先于构造器原因

    我们那一段代码作为例子说明下,代码如下:

    class Init {
        public Init() {
            System.out.println("无参构造器");
        }
        public Init(int a) {
            System.out.println("有参构造器");
     
        }
     
        {
            System.out.println("实例代码块1");
        }
     
        {
            System.out.println("实例代码块2");
        }
     
        {
            System.out.println("实例代码块3");
        }
     
        static {
            System.out.println("静态初始化块1");
        }
     
        static {
            System.out.println("静态初始化块2");
        }
     
        public void method(){
            {
                System.out.println("普通初始化块");
            }
        }
    }

    接下来让我们看看 , Init.java编译完的的字节码文件(Init.class)

    Java オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?

    从这个字节码文件就可以很清晰的看出, 实例代码块实际上是被依次放到了构造方法的第一句, 所以可以的出此结论: 实例代码块的执行顺序是优先于构造器的。

    以上がJava オブジェクトの初期化中にコード ブロックとコンストラクターが呼び出される順序は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。