Javaは、仮想マシンの観点からクラスのインスタンス化の順序が何であるかを分析します。

青灯夜游
リリース: 2018-10-20 15:51:14
転載
2164 人が閲覧しました

この記事では、仮想マシンの観点から見たクラスのインスタンス化順序についての Java の分析について説明します。困っている友人は参考にしていただければ幸いです。

1. まず、サンプル コード (Son.java & Father.java) を示します。

public class Father {    
    public static int a=10;//父类的静态变量    static{//父类的静态代码块
        a=20;
    }
    {//父类的构造代码块
        a=30;
    }    
    public Father() {//父类的构造方法
        a=40;
    }
}
ログイン後にコピー
public class Son extends Father{    
    public static int s=10;//子类的静态变量    public int k=20;//子类的实例变量    static{//子类的静态代码块
        s=20;
    }
    {//子类的构造代码块
        s=30;
    }    public Son() {//子类的构造函数
        s=40;
    }
    {//子类的构造代码块
        s=50;
    }
}
ログイン後にコピー

2. Son.java ファイルを Son.class ファイルにコンパイルし、次に javap を使用して逆コンパイルします。 Son を表示する バイトコード命令は、Son のロード シーケンスを分析するために使用され、理解しやすくなります (javap -v -c Son > p.txt)。

3. コード「new Son();」を実行した後、クラスの読み込み順序を分析します。

以下の static{}; は 関数です。

static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: bipush        10
         2: putstatic     #11                 // Field s:I--------------------------顺序执行静态变量的赋值
         5: bipush        20
         7: putstatic     #11                 // Field s:I--------------------------顺序执行静态代码块
        10: return
ログイン後にコピー
  public packet1020.Son();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0         
         1: invokespecial #16                 // Method packet1020/Father."<init>":()V--------------------执行父类的<init>函数(顺序不变,第一个)
         4: aload_0         
         5: bipush        20
         7: putfield      #18                 // Field k:I------------------------------------------------按顺序收集实例变量赋值
        10: bipush        30
        12: putstatic     #11                 // Field s:I------------------------------------------------按顺序收集构造代码块
        15: bipush        50
        17: putstatic     #11                 // Field s:I------------------------------------------------按顺序收集构造代码块
        20: bipush        40
        22: putstatic     #11                 // Field s:I------------------------------------------------最后执行自己的构造函数代码(顺序不变,最后一个)
        25: return
ログイン後にコピー

分析の開始:

1. 初期化フェーズでは、最初に親クラスの 関数を実行し、次にサブクラスの を実行します。関数、静的変数割り当て、静的コード ブロックの順に説明します。

2. コード内でコンストラクターが実行されるため、 関数が実行されます。

結論:

1. 静的変数の割り当ては、親クラスの静的コード ブロックで順次実行されます。

2. 静的変数の割り当ては、サブクラスの静的コードで順次実行されます。ブロック

3. 親クラスでインスタンス変数の代入を順次実行し、コード ブロックを構築します。

#4. 親クラスのコンストラクターでインスタンス変数の代入を順次実行し、コード ブロックを構築します。サブクラス

6 のサブクラス コンストラクター

名前の説明: Zhou Zhiming 氏による「Java 仮想マシンの詳細: JVM の高度な機能とベスト プラクティス」からの抜粋

1. はい、クラスを初期化する必要があるのは 4 つの状況のうち 3 つ目 ( 関数の実行) だけです。クラスを初期化するときは、最初に親クラスを初期化します。これが、親クラスの 関数が子クラスの 関数より先に実行される理由です。

2. 機能: コンパイラは、クラス内のすべての静的変数の代入アクションを自動的に収集し、ソース コード内の順序に従って静的コード ブロック内のステートメントをマージします。

3. 関数: 最初に親クラスの 関数を呼び出し、次にコンパイラが順序に従ってクラス内のインスタンス変数の代入演算と構築コード ブロックを自動的に収集します。ソース コードでは、 のステートメントがマージされてからコンストラクター メソッドの前に挿入され、最後にプログラマー自身が作成したコンストラクター コードになります。

コンストラクション コード ブロックの実行順序はコンストラクター関数に先行します

<init>(){
  1.调用父类<init>方法
  2.顺序执行实例变量的赋值操作和构造代码块
  3.程序员自己的构造函数方法代码
}
ログイン後にコピー
要約: 上記がこの記事の全内容です。皆さんの学習に役立つことを願っています。関連チュートリアルの詳細については、

Java ビデオ チュートリアル

Java 開発グラフィック チュートリアルブートストラップ ビデオ チュートリアルをご覧ください。

以上がJavaは、仮想マシンの観点からクラスのインスタンス化の順序が何であるかを分析します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート