これらのコード文は同等ですか?それらの間に違いはありますか?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
これらのコード文は同等ですか?それらの間に違いはありますか?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
回答:
はい、大きな違いがあります-後者は例外を飲み込み(確かにそれを表示します)、一方、最初のものはそれを伝播させます。(私はそれshowException
がそれを再投げしないと仮定しています。)
したがって、最初のメソッドを呼び出して「何かを行う」ことが失敗した場合、呼び出し元は例外を処理する必要があります。2番目のメソッドを呼び出すと、「何かをする」失敗した場合、呼び出し側は、すべての例外は表示されません...一般的に悪いことである、場合を除きshowException
ました本当に間違っていたものは何でも固定例外を、処理され、一般的に確認しましたそれcalculateArea
はその目的を達成しました。
あなたはせずに最初のメソッドを呼び出すことはできませんので、このことを伝えることができるでしょういずれかのキャッチException
自分自身をかあなたの方法でもそれを投げるかもしれないことを宣言する。
1つ目throws Exception
は、呼び出し元がを処理する必要があるためException
です。2つ目はException
内部的にキャッチして処理するため、呼び出し元は例外処理を行う必要がありません。
はい、それらの間には大きな違いがあります。最初のコードブロックでは、呼び出し元のコードに例外を渡します。2番目のコードブロックでは、自分で処理します。どの方法が正しいかは、あなたが何をしているのかに完全に依存します。場合によっては、コードで例外を処理する必要があります(たとえば、ファイルが見つからず、作成したい場合)が、呼び出し元のコードで例外を処理する(ファイルが見つからない)場合があります。新しいものを指定するか作成する必要があります)。
一般的に言えば、一般的な例外をキャッチする必要はありません。代わりに、次のような、特定のもの、キャッチしたいと思うFileNotFoundException
かIOException
、彼らが異なることを意味することができますのでを。
スローを使用できない特定のシナリオが1つあり、try-catchを使用する必要があります。「オーバーライドされたメソッドは、その親クラスがスローしているもの以外の追加の例外をスローすることはできません」というルールがあります。try-catchを使用して処理する必要がある追加の例外がある場合。このコードスニペットを検討してください。単純な基本クラスがあります
package trycatchvsthrows;
public class Base {
public void show()
{
System.out.println("hello from base");
}
}
そしてそれは派生クラスです:
package trycatchvsthrows;
public class Derived extends Base {
@Override
public void show() {
// TODO Auto-generated method stub
super.show();
Thread thread= new Thread();
thread.start();
try {
thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// thread.sleep(10);
// here we can not use public void show() throws InterruptedException
// not allowed
}
}
thread.sleep()を呼び出す必要がある場合、try-catchの使用を強制されます。ここでは使用できません。
public void show() throws InterruptedException
オーバーライドされたメソッドは追加の例外をスローできないためです。
「同一」とはあなたが行動を指していると思います。
関数の動作は次のようにして決定できます。
1)戻り値
2)スローされた例外
3)副作用(つまり、ヒープ、ファイルシステムなどの変更)
この場合、最初のメソッドは例外を伝播し、2番目のメソッドはチェック済み例外をスローせず、ほとんどの未チェック例外も飲み込むため、動作は異なります。
ただし、「何かを行う」が例外をスローしないことが保証されている場合、動作は同じになります(最初のバージョンでは、コンパイラーは呼び出し側が例外を処理する必要があります)
-編集-
API設計の観点から見ると、メソッドは契約で完全に異なります。また、クラスExceptionをスローすることはお勧めしません。より具体的なものをスローして、呼び出し側が例外をより適切に処理できるようにします。
例外をスローした場合、(これをオーバーライドする)子メソッドが例外を処理する必要があります
例:
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
このメソッドの呼び出し元は、この例外をキャッチするか、メソッドのシグネチャで再スローされるように宣言する必要があります。
private void calculateArea() throws Exception {
// Do something
}
以下のtry-catchブロックの例で。このメソッドの呼び出し元は、すでに処理されているため、例外の処理について心配する必要はありません。
private void calculateArea() {
try {
// Do something
} catch (Exception e) {
showException(e);
}
}
private void calculateArea() throws Exception {
....do something
}
これは例外をスローするため、呼び出し元はその例外を処理する必要がありますが、呼び出し元が例外を処理しない場合、jvmに渡され、プログラムが異常終了する可能性があります。
一方、2番目のケースでは:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
ここでは、例外は呼び出し先によって処理されるため、プログラムが異常終了する可能性はありません。
トライキャッチが推奨されるアプローチです。
IMO、
コンパイラーを説得するために主にチェック例外で使用されるキーワードをスローしますが、プログラムの正常終了を保証するものではありません。
キーワードをスローすると、例外処理の責任が
呼び出し元(JVMまたは別のメソッド)に委任されます。
Throwsキーワードは、チェックされた例外にのみ必要です。チェックされていない例外の場合、throwsキーワードは使用されません。