[インタビューの質問] Javaクラスの初期化とインスタンス化、およびその他の重要なテストサイト

序文:

この記事では、古典的なJavaインタビューの質問を使用して、Javaクラスとインスタンスオブジェクトの初期化とインスタンス化について説明します。主な内容は以下の3点です。

1.クラス初期化プロセス(最初)

2.インスタンス初期化プロセス(後)

3.メソッドの書き換え(注)

最初にトピックを見て、出力を分析します。

親クラス: 

public class Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(1)");
    }
    Father() {
        System.out.println("(2)");
    }

    {
        System.out.println("(3)");
    }

    public int test() {
        System.out.println("(4)");
        return 1;
    }
    public static int method() {
        System.out.println("(5)");
        return 1;
    }
}

サブクラス: 

public class Son extends Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.println("(6)");
    }
    Son() {
        System.out.println("(7)");
    }
    {
        System.out.println("(8)");
    }
    public int test() {
        System.out.println("(9)");
        return 1;
    }

    public static int method() {
        System.out.println("(10)");
        return 1;
    }
    //TEST
    public static void main(String[] args) {
        Son son  = new Son();
        System.out.println();
        Son son1 = new Son();
    }

}

 1.クラス初期化プロセス

(1)mainメソッドmainが配置されているクラスをロードして初期化する必要があります(mainにコンテンツがない場合でも)

(2)インスタンスオブジェクトを作成すると、初期化クラスが最初にロードされます

(3)サブクラスの初期化では、最初に親クラスを初期化する必要があります 

(4)クラスの初期化は、実際には<clinit>()メソッドの実装であり、静的クラス変数静的コードブロックで構成され、上から下に実行されます。

      要約すると、まずメインメソッドmain()が配置されているクラスが読み込まれて初期化され(1)、親クラス(3)が読み込まれて初期化されてから、このサブクラスが読み込まれます。つまり、静的クラス変数j = method()です。出力1]、静的コードブロック[出力5]、上から下に実行;親クラスが読み込まれた後、Sonの静的クラス変数j = method()[出力10]、静的コードブロック[出力6]を上から読み込み始めます次のステップ(4)に進みます。

2.インスタンスの初期化プロセス

(1)インスタンスの初期化は、実際には<init>()メソッドを実行することです。<clinit>のクラスは1つだけですが、<init>にあるのと同じ数のコンストラクターがあります(パラメーターの有無にかかわらず複数のコンストラクターがある場合があります)。 。静的クラス変数静的コードブロックコンストラクター3つの部分で構成されています。このうち、非静的インスタンス変数と非静的コードブロック実行順序は上から下で、コンストラクターが最後に実行されます。

(2)<init>()メソッドの最初の行はsuper()であり、記述されているかどうかに関係なく存在します。

要約すると、サブクラスのインスタンス化メソッドは、次の4つのステップに分かれています。

  • 1.スーパー()=>親クラスのインスタンス化(ここでも3つのステップ)
  • 2.非静的インスタンス変数をサブクラス化し、非静的コードブロックの実行順序を上から下に
  • 3.サブクラスのコンストラクタ

1. 1つ目はsuper()で、親クラスがインスタンス化され、非静的変数i = testですが、ここではメソッドの書き換えが含まれ、非静的メソッドの前のデフォルトの呼び出しオブジェクトはthisであり、これは作成されるオブジェクトを指します、つまり、サブクラスオブジェクトなので、i = testはサブクラスのテストメソッドを出力します:[出力9];親クラスの非静的コードブロック:[出力3]、親クラスのコンストラクターが最後:[出力2] 】

2.非静的変数i =サブクラスのテストメソッド:[出力9];サブクラスの非静的コードブロック:[出力8];上から順に実行されます

3.最後のサブクラスコンストラクター:[出力7]

2番目のSonオブジェクトが作成され、再び[932987]が出力されるため、合計出力ビット[1 5 10 6 9 3 2 9 8 7 9 3 2 9 8 7]

3.メソッドの書き換えについて

サブクラスが親クラスのメソッドを書き換える場合、サブクラスが呼び出したコードは、サブクラスによって書き換えられたコードである必要があります。メソッドtest()がサブクラスによってオーバーライドされ、メソッドメソッドがオーバーライドされないのはなぜか疑問に思われるかもしれません。では、どのメソッドを書き換えられないのでしょうか?

(1)最後のメソッドは書き換えられない

(2)静的メソッドは書き換えできません

(3)privateなどのサブクラスの非表示メソッドはオーバーライドできません

元の記事を20件公開 15 獲得 ビュー216

おすすめ

転載: blog.csdn.net/qq_37414463/article/details/105460340