JAvaクラスのロードタイミングとオブジェクトnewの順序に関する問題のまとめ
3674 ワード
一、どのような場合にクラスを初期化しなければなりませんか?
1.new,getstatic,putstatic,invokestaticの4バイト命令に遭遇した場合、クラスが初期化されていない場合は、その初期化をトリガーする必要があります.この4つのバイト命令の一般的なシーン:newインスタンス化オブジェクトを使用して、dinal修飾された場合、コンパイラが結果を定数プールに入れた静的フィールドを除く静的フィールドを読み取りまたは設定し、クラスの静的メソッドを呼び出します.シーンは基本的に上のバイト命令に対応します.
2.javaを使用する.lang.reflectパケットのメソッドがクラスを反射呼び出した場合、このクラスが初期化されていなければ初期化
3.クラスを初期化するとき、その親が初期化されていないことに気づいたら、まずその親を初期化し、親の初期化は同じです.
4.仮想マシンが起動すると、ユーザーは実行するメインクラス(main関数を含むクラス)を指定して初期化する必要があります.
5.jdk 1を用いる場合.7の動的言語がサポートされている場合java.lang.invoke.MethodHandleインスタンスの最終結果のEREF_getstatic, EREF_putstatic, EREF_invokestaticのメソッドハンドルで、対応するクラスが初期化されていない場合は初期化します.
この2でクラスの初期化シーンがトリガーされ、1つのクラスへのアクティブな参照となります.それ以外は、すべての参照クラスのメソッドがクラスの初期化をトリガーしません.
いくつかの受動引用例:
1.親の静的フィールドを参照し、子の初期化は行われません.
最終出力結果は、サブクラスオブジェクトが初期化されていないことがわかります.
sA sa
2.static変数修飾final定数を参照すると、コンパイルされたアキュムレータに定数が既に定数プールに追加されているため、サブクラスと親クラスの初期化はトリガーされません.
コードを参照:
出力結果:sb
4.しかしfinalに修飾された定数はすべてこのような結果ではないでしょうか.答えはもちろんNo!、この定数はコンパイル期間定数でなければなりませんが、次の例がありますか?
出力結果:
sA
sB
sb
このように、まずClassBを初期化したとき、親が初期化されていないことに気づき、まず父を初期化し、息子を再初期化しました.
3.配列定義でクラスを参照し、クラスの初期化はトリガーされません
出力結果が空で、ClassAを設定してもClassBは初期化されていないと思います!
次に、いくつかの関連する問題を見ます.
タイトル1:
以上のプログラム出力の結果、正しいのは?
答え:
DACBCB
解析: mainが存在するクラスが最初に初期化して静的ブロックコードを実行する:D main関数出力:A は、Mainクラスが初期化されているため、Mainクラスをインスタンス化する.静的コードブロックは、クラスの初期化時に1回実行されることを目的としています.同時に構築コードブロックは構築関数より優先的に実行される:CB 同上出力:CB
参考文献:
周志明Java仮想マシン[M].機械工業出版社、2013.
1.new,getstatic,putstatic,invokestaticの4バイト命令に遭遇した場合、クラスが初期化されていない場合は、その初期化をトリガーする必要があります.この4つのバイト命令の一般的なシーン:newインスタンス化オブジェクトを使用して、dinal修飾された場合、コンパイラが結果を定数プールに入れた静的フィールドを除く静的フィールドを読み取りまたは設定し、クラスの静的メソッドを呼び出します.シーンは基本的に上のバイト命令に対応します.
2.javaを使用する.lang.reflectパケットのメソッドがクラスを反射呼び出した場合、このクラスが初期化されていなければ初期化
3.クラスを初期化するとき、その親が初期化されていないことに気づいたら、まずその親を初期化し、親の初期化は同じです.
4.仮想マシンが起動すると、ユーザーは実行するメインクラス(main関数を含むクラス)を指定して初期化する必要があります.
5.jdk 1を用いる場合.7の動的言語がサポートされている場合java.lang.invoke.MethodHandleインスタンスの最終結果のEREF_getstatic, EREF_putstatic, EREF_invokestaticのメソッドハンドルで、対応するクラスが初期化されていない場合は初期化します.
この2でクラスの初期化シーンがトリガーされ、1つのクラスへのアクティブな参照となります.それ以外は、すべての参照クラスのメソッドがクラスの初期化をトリガーしません.
いくつかの受動引用例:
1.親の静的フィールドを参照し、子の初期化は行われません.
public class ClassA {
public static String a="sa";
static {
System.out.println("sA");
}
}
public class ClassB extends ClassA {
public static String b="sb";
static {
System.out.println("sB");
}
}
//
public class TestAB {
public static void main(String[] args){
System.out.println(ClassB.a);
}
}
最終出力結果は、サブクラスオブジェクトが初期化されていないことがわかります.
sA sa
2.static変数修飾final定数を参照すると、コンパイルされたアキュムレータに定数が既に定数プールに追加されているため、サブクラスと親クラスの初期化はトリガーされません.
コードを参照:
public class ClassA {
public static String a="sa";
static {
System.out.println("sA");
}
}
public class ClassB extends ClassA {
public static String final b="sb";
static {
System.out.println("sB");
}
}
//
public class TestAB {
public static void main(String[] args){
System.out.println(ClassB.b);
}
}
出力結果:sb
4.しかしfinalに修飾された定数はすべてこのような結果ではないでしょうか.答えはもちろんNo!、この定数はコンパイル期間定数でなければなりませんが、次の例がありますか?
public class ClassA {
public static String a="sa";
static {
System.out.println("sA");
}
}
public class ClassB extends ClassA {
public static String final b= new String("sb");
static {
System.out.println("sB");
}
}
//
public class TestAB {
public static void main(String[] args){
System.out.println(ClassB.b);
}
}
出力結果:
sA
sB
sb
このように、まずClassBを初期化したとき、親が初期化されていないことに気づき、まず父を初期化し、息子を再初期化しました.
3.配列定義でクラスを参照し、クラスの初期化はトリガーされません
public class ClassA {
public static String a="sa";
static {
System.out.println("sA");
}
}
public class ClassB extends ClassA {
public static String b="sb";
static {
System.out.println("sB");
}
}
//
public class TestAB {
public static void main(String[] args){
// System.out.println(ClassB.b);
ClassB[] classBS = new ClassB[100];
}
}
出力結果が空で、ClassAを設定してもClassBは初期化されていないと思います!
次に、いくつかの関連する問題を見ます.
タイトル1:
public class Main {
public static void main(String[] args) {
System.out.println("A");
new Main();
new Main();
}
public Main() {
System.out.println("B");
}
{
System.out.println("C");
}
static {
System.out.println("D");
}
}
以上のプログラム出力の結果、正しいのは?
答え:
DACBCB
解析:
参考文献:
周志明Java仮想マシン[M].機械工業出版社、2013.