2

そこで、Car オブジェクトの配列をファイルに書き出します。次に、車の変数でそれらを読み戻そうとすると、ステートメントに設定されますcars = (Car[])in.readObject();。ただし、デバッガーでステップ実行すると、try-catch ブロックを終了すると、cars 変数が「設定解除」されます。

Car[] cars;
try {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)));
    cars = (Car[])in.readObject();
    in.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

一方、cars 変数をたとえば空の配列に初期化すると、cars 変数は try-catch ブロックの後も設定されたままになります。

Car[] cars = new Car[0];
try {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename)));
    cars = (Car[])in.readObject();
    in.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

では、事前に初期化した場合にのみ、in.readObject で読み取った Car[] への参照が cars 変数に保持されるのはなぜですか? 車を初期化するかどうかに関係なく、なぜ違いが生じるのかわかりません...どちらの方法でも、try-catch ブロックの Car[] オブジェクトを読み取るための参照を取得します。

一部の遅延初期化が発生しているようです..仮想マシンは、try catch-block で cars オブジェクトのスペースを宣言しているだけであるため、ブロックを終了すると範囲外になります...

4

4 に答える 4

4

「未設定」にはなりませんが、最初の例のブロックの後のコードでの値を読み取ることはできません。これは、確実に割り当てられていないためです。ブロックの最初の 2 つのステートメントのいずれかで例外がスローされた場合、それに値は割り当てられません。carstry/catchtry

やみくもに例外をキャッチするだけでなく、スタック トレースを出力した後に続行することで、これを修正できます。

  • 関心のある特定の例外のみをキャッチします。catch (Exception e)ほとんどの場合、悪い考えです。
  • 必ずしも何かをキャッチする必要はありません。メソッドは実際に例外を処理できますか? そうでない場合は、スローされる可能性があることを宣言してください。いつでもキャッチして投げることができます。
  • 本当に処理できる場合は、catch ブロックにデフォルト値を実際に割り当てる必要があるかもしれません

これらの箇条書きに従うと (再スローするか、バブルアップさせるか、適切な値を割り当てるかのいずれか)、変数は確実に割り当てられ、すべてがうまくいきます。

于 2012-10-19T13:13:19.117 に答える
0

変数は、変数の最後の使用を超えたコード内のポイントに到達するとすぐに、実行時に合法的に「設定解除」される可能性があります。この種の最適化は、HotSpot によって定期的に行われ、大量のメモリを節約でき、OutOfMemoryError. ただし、これはおそらくデバッグ セッションでは発生しません。

コンパイル時に、静的アナライザーは、var のスコープを try ブロック内のみに絞り込んで、var が実際に try 内で宣言されているかのようにコンパイルできると判断できます。これは、2 つのコード サンプル間で異なる動作が見られる理由を正確に説明します。2 番目の例では、外側のスコープで割り当てるため、絞り込みができません。

于 2012-10-19T13:13:26.550 に答える