学习是最好的投资!
リーリー
上記のコードはバイトコードにコンパイルされ、次のように逆変換されます:
最も簡単な答えは、new A() のたびにオブジェクトが作成されるということです。 new A()时都会创建一个对象。
new A()
下面分析一下稍微详细一点的过程1.程序执行后首先进入main函数,然后第一次执行new A();2.由于没有显示的构造函数,编译器在编译的时候会生成一个无参构造函数
main
public A(){ }
3.进入上面的构造函数后先要初始化成员变量,也就是 A a = new A();4.这里就到的问题的关键,成员变量A初始化还是new A()继续调用2中的构造函数。5.接着就会重复2、3、4的步骤,直到这个线程的栈空间不够用,抛出StackOverflowError错误。
A a = new A();
A
StackOverflowError
这里还要普及一点方法调用的知识,在JVM中,每个线程都会分配一定的栈空间(非共享),这个栈空间可以是固定的可以是动态扩展的,不同的JVM这里的实现方式可以不同。线程中每执行一个方法,这个方法就会以栈帧的形式压入线程栈中。
JVM
上面出现StackOverflowError
システムがクラスをロードするとき、またはクラスのインスタンスを作成するとき、システムは自動的にメンバー変数にメモリ空間を割り当て、メモリ空間を割り当てた後、自動的に初期値をメンバー変数に割り当てます。
ローカル変数を定義した後、使用する前に明示的に初期化する必要があります。システムはローカル変数を初期化しません。これは、ローカル変数が定義された後、プログラムが初期値を変数に割り当て、その初期値をこのメモリに保存するまで、システムはその変数にメモリ空間を割り当てないことを意味します。
java.lang.StackOverflowError はメモリ オーバーフローと無限ループを意味します。質問者はクラス A 内にクラス A のインスタンスを作成すべきではありません。A() は、クラス A に直接 A を書き込む a = new A () と同等です。 ; インスタンスの無限反復作成が発生し、最終的にはメモリ オーバーフローが発生し、プログラムの 4 行目にエラーがあることが示され、エラーが繰り返し発生します
Java の知識を学び、ガイダンスを交換するために、質問者が私のホームページに来ることを歓迎します。質問者が言及した知識ポイントは、私のホームページの Java オブジェクト指向 (パート 1) に記載されています: https://segmentfault.com/a/。 11.. .
上記のお二人が非常に分かりやすく説明してくださっていますが、簡単に言うとクラスAに独自のインスタンス変数aを追加します。これ自体は問題ありませんが、インスタンスの初期化処理の中にaの初期化を入れています。 new A() を 1 回呼び出すと、無限呼び出しループに陥るため、スタックがオーバーフローします。
これは非常に明白な再帰呼び出しであり、終了条件がないため、間違いなくメモリ オーバーフローが発生します。再帰はメソッド内でメソッド自体を呼び出すことであり、あなたが与えたケースは特別であり、コンストラクターメソッドです。理由は単純です。
リーリー
上記のコードはバイトコードにコンパイルされ、次のように逆変換されます:
リーリー最も簡単な答えは、
new A()
のたびにオブジェクトが作成されるということです。new A()
时都会创建一个对象。下面分析一下稍微详细一点的过程
1.程序执行后首先进入
main
函数,然后第一次执行new A()
;2.由于没有显示的构造函数,编译器在编译的时候会生成一个无参构造函数
3.进入上面的构造函数后先要初始化成员变量,也就是
A a = new A();
4.这里就到的问题的关键,成员变量
A
初始化还是new A()
继续调用2中的构造函数。5.接着就会重复2、3、4的步骤,直到这个线程的栈空间不够用,抛出
StackOverflowError
错误。这里还要普及一点方法调用的知识,在
JVM
中,每个线程都会分配一定的栈空间(非共享),这个栈空间可以是固定的可以是动态扩展的,不同的JVM
这里的实现方式可以不同。线程中每执行一个方法,这个方法就会以栈帧的形式压入线程栈中。上面出现
もう少し詳細なプロセスを分析してみましょうStackOverflowError
1. プログラムが実行されると、最初に
main
関数に入り、最初のnew A()
が実行されます。 time;2 .明示的なコンストラクターがないため、コンパイラーはコンパイル中にパラメーターなしのコンストラクターを生成します🎜 リーリー 🎜3. 上記のコンストラクターを入力した後、まずメンバー変数を初期化する必要があります。つまり、
A a = new A();
4. ここで問題の鍵となるメンバー変数が登場します。
A
の初期化またはnew A()
は、2 のコンストラクターを呼び出し続けます。5. 次に、このスレッドのスタック領域が不足して
StackOverflowError
エラーがスローされるまで、ステップ 2、3、および 4 が繰り返されます。 🎜 🎜ここでは、メソッド呼び出しに関する知識を広める必要もあります。JVM
では、各スレッドに特定のスタック領域 (非共有) が割り当てられます。このスタック領域は固定または動的に拡張できます。ここでのJVM
実装は異なる場合があります。スレッド内でメソッドが実行されるたびに、そのメソッドはスタック フレームの形式でスレッド スタックにプッシュされます。 🎜 🎜StackOverflowError
が上に表示されるのは、コンストラクター メソッドが継続的に呼び出され、スタック フレームが継続的に作成されてスレッド スタックにプッシュされるためです。最終的にはスタック領域が不足し、スタック オーバーフローが発生します。 🎜メモリ上の変数と演算機構の初期化
メモリ上のメンバ変数と演算機構の初期化
システムがクラスをロードするとき、またはクラスのインスタンスを作成するとき、システムは自動的にメンバー変数にメモリ空間を割り当て、メモリ空間を割り当てた後、自動的に初期値をメンバー変数に割り当てます。
メモリ内のローカル変数と演算機構の初期化
ローカル変数を定義した後、使用する前に明示的に初期化する必要があります。システムはローカル変数を初期化しません。これは、ローカル変数が定義された後、プログラムが初期値を変数に割り当て、その初期値をこのメモリに保存するまで、システムはその変数にメモリ空間を割り当てないことを意味します。
正しいコード
リーリーjava.lang.StackOverflowError例外
java.lang.StackOverflowError はメモリ オーバーフローと無限ループを意味します。質問者はクラス A 内にクラス A のインスタンスを作成すべきではありません。A() は、クラス A に直接 A を書き込む a = new A () と同等です。 ; インスタンスの無限反復作成が発生し、最終的にはメモリ オーバーフローが発生し、プログラムの 4 行目にエラーがあることが示され、エラーが繰り返し発生します
知識の補足
Java の知識を学び、ガイダンスを交換するために、質問者が私のホームページに来ることを歓迎します。質問者が言及した知識ポイントは、私のホームページの Java オブジェクト指向 (パート 1) に記載されています: https://segmentfault.com/a/。 11.. .
上記のお二人が非常に分かりやすく説明してくださっていますが、簡単に言うとクラスAに独自のインスタンス変数aを追加します。これ自体は問題ありませんが、インスタンスの初期化処理の中にaの初期化を入れています。 new A() を 1 回呼び出すと、無限呼び出しループに陥るため、スタックがオーバーフローします。
これは非常に明白な再帰呼び出しであり、終了条件がないため、間違いなくメモリ オーバーフローが発生します。再帰はメソッド内でメソッド自体を呼び出すことであり、あなたが与えたケースは特別であり、コンストラクターメソッドです。理由は単純です。