このJavaのコードに関する設問で、選択肢CとDが正しい理由を説明します。
まず、選択肢Cが「mainメソッドとsampleメソッドの両方にthrows Exceptionを追加する」と述べています。コードを見ると、sample
メソッド内で Exception
を投げる可能性があります(if (str == null) throw new Exception();
)。しかし、この例外は sample
メソッド内で捕捉(catch)されておらず、呼び出し元に伝播されます。つまり、main
メソッドもこの例外を捕捉するか、または throws Exception
を使用して呼び出し元に伝播させる必要があります。main
メソッドがこの例外を捕捉しないため、throws Exception
を追加する必要があります。
次に、選択肢Dです。これは「sampleメソッドの宣言にthrows Exceptionを追加し、catchブロックの型をExceptionに変更する」と説明しています。この変更が必要な理由は、sample
メソッドが Exception
を投げる可能性があるためです。現在の catch
ブロックでは RuntimeException
だけを捕捉しており、Exception
は捕捉されません。これは、RuntimeException
が Exception
のサブクラスであるため、より広範な例外タイプを捕捉するために Exception
を使用する必要があります。
これらの変更を加えることで、コードはすべての可能性のある例外を適切に処理できるようになります。選択肢CとDが正しい答えとされているのは、これらの理由に基づいています。
追記
選択肢CとDを適用した場合、Javaプログラムのコードは以下のように変更されます。
選択肢C: main
メソッドと sample
メソッドの両方に throws Exception
を追加
この選択肢を適用すると、main
メソッドと sample
メソッドが Exception
を投げる可能性があると宣言され、呼び出し元がこれを処理する責任を持つことになります。
public class Main {
public static void main(String[] args) throws Exception { // throws Exceptionを追加
try {
if (args.length == 0) {
sample(null);
} else {
sample(args[0]);
}
} catch (RuntimeException e) {
System.out.println("error");
}
}
private static void sample(String str) throws Exception { // throws Exceptionを追加
if (str == null) throw new Exception();
throw new RuntimeException();
}
}
選択肢D: sample
メソッドの宣言に throws Exception
を追加し、catch
ブロックの型を Exception
に変更する
この選択肢を適用すると、sample
メソッドが Exception
を投げることを宣言し、main
メソッドの catch
ブロックでより広範な Exception
を捕捉します。
public class Main {
public static void main(String[] args) {
try {
if (args.length == 0) {
sample(null);
} else {
sample(args[0]);
}
} catch (Exception e) { // RuntimeExceptionからExceptionへ変更
System.out.println("error");
}
}
private static void sample(String str) throws Exception { // throws Exceptionを追加
if (str == null) throw new Exception();
throw new RuntimeException();
}
}
選択肢CとDのどちらもコードを正しくコンパイル可能にし、sample
メソッドから投げられる Exception
と RuntimeException
を適切に扱えるようにします。選択肢Dは、Exception
による広範なエラー処理を可能にし、全ての例外タイプをキャッチできるようにしています。一方、選択肢Cはmain
メソッドが例外を投げることを宣言していますが、これによりこのメソッドを呼び出すすべての上位メソッドも例外処理を行う必要が生じます。
補足
選択肢CとDが提案する解決策は類似していますが、それぞれ異なるアプローチを取っている点に注意が必要です。両選択肢の理解と使い分けについて説明します。
選択肢C
適用される変更: main
メソッドと sample
メソッドの両方に throws Exception
を追加します。
目的: この変更により、sample
メソッドから Exception
が投げられる場合、その例外を main
メソッドがキャッチしなくても良いようになります。代わりに、main
メソッドも例外を呼び出し元に伝播させることが宣言されます。これにより、例外処理の責任が main
メソッドの呼び出し元に移されます。
利用シナリオ: アプリケーション全体で例外処理のポリシーが統一されており、特定の例外が最上位まで伝播してから一括でキャッチされるべき場合や、例外処理の責任を明確に分離したい場合に適しています。
選択肢D
適用される変更: sample
メソッドの宣言に throws Exception
を追加し、main
メソッド内の catch
ブロックの例外タイプを RuntimeException
から Exception
に変更します。
目的: sample
メソッドが Exception
を投げる可能性があることを宣言し、main
メソッド内の catch
ブロックで Exception
(及びそのすべてのサブクラス)をキャッチできるようにします。これにより、main
メソッドで発生したすべての例外をローカルで処理し、プログラムの安定性を高めることができます。
利用シナリオ: メソッド内で発生したすべての例外をその場で処理し、エラーハンドリングをメソッド内にカプセル化したい場合に適しています。これは、プログラムの他の部分に影響を与えずにエラーを管理するために有用です。
CとDの違いと使い分け
- 選択肢Cは例外の伝播を推進し、上位のメソッド(またはエントリポイントの外部)で一括して例外を処理する戦略です。このアプローチは、例外処理をアプリケーション全体で一元管理したい場合や、例外をさらに外部に伝えることが適切な場合に役立ちます。
- 選択肢Dは、特定のメソッド内で完全に例外を処理することを目的としています。これにより、エラーハンドリングがそのメソッド内に閉じられ、他のメソッドの実行に影響を与えないようにします。これは、エラーの影響を局所化して処理する必要がある場合に有効です。
これらの違いを理解することで、プログラムの設計において適切なエラーハンドリング戦略を選択する際の判断材料とすることができます。
Top comments (0)