- PR -

例外処理についてのコンパイルエラー

1
投稿者投稿内容
がお
会議室デビュー日: 2005/12/02
投稿数: 17
投稿日時: 2005-12-29 11:19
例外処理についてのコンパイルエラーで、
疑問に思っているところがあるのですが、
上の例だとOKなのですが、下の例ではコンパイルエラーが
発生します。
何故なのでしょうか?
java.lang.Exception は報告されません。スローするにはキャッチまたは、スロー宣言をしなければなりません。
とエラーが出ます

コード:
***************************************
こちらはOK
	static int cal(String str1, String str2) {
		int i=0,j=0;
		try {
			i=Integer.parseInt(str1);
			j=Integer.parseInt(str2);
				//	整数に直せないと例外
			return i/j;
				//0除算で例外発生
		} catch (ArithmeticException e) {
			System.out.println("メソッド内の例外処理:" + e);
			throw e;
		}
	}
***************************************
こちらはコンパイルエラー
catch (Exception e) の部分が上と違う

	static int cal(String str1, String str2) {
		int i=0,j=0;
		try {
			i=Integer.parseInt(str1);
			j=Integer.parseInt(str2);
				//	整数に直せないと例外
			return i/j;
				//0除算で例外発生
		} catch (Exception e) {
			System.out.println("メソッド内の例外処理:" + e);
			throw e;
		}
	}


ibara
常連さん
会議室デビュー日: 2002/11/15
投稿数: 26
投稿日時: 2005-12-29 12:32
ArithmeticExceptionはjava.lang.RuntimeExceptionのサブクラスであり、つまり非検査例外だからです。
http://www.y-adagio.com/public/standards/tr_javalang2/exceptions.doc.html#44121

上のコードでは、cal()メソッドがthrow e;でスローするのはArithmeticExceptionですから、これをthrows ArithmeticExceptionとする必要はありません。
しかし、下のコードではjava.lang.Exceptionをthrow e;でスローしていますので、これをどうしてもスローしたいならばthrows Exceptionという記述をするか、スローするのをやめる(catch Exception eで終わらせる)しかないでしょ?というのがエラーの意味だと思います。
ただし、throws Exceptionはコンパイルは通りますがやってはならないです。意味もありませんし、このcalメソッドを呼ぶ側からすれば甚だ迷惑だからです。

[ メッセージ編集済み 編集者: ibara 編集日時 2005-12-29 12:37 ]
末記入
会議室デビュー日: 2005/03/18
投稿数: 4
お住まい・勤務地: いなか
投稿日時: 2005-12-29 12:35
検査例外と実行時例外の違いです。
検査例外をthrowするメソッドは throws で明示的にthrowする例外を示さなければなりません。

The Java Language Specification, Third Editionの11.2を確認してくださいな。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-12-29 12:43
引用:

ただし、throws Exceptionはコンパイルは通りますがやってはならないです。意味もありませんし、このcalメソッドを呼ぶ側からすれば甚だ迷惑だからです。


フレームワーク等を利用したクラス設計を行う場合、
例外処理を上位クラスに委譲するために、
すべてthrows Exceptionでスローするという設計もあります。
(上位クラスに委譲する必要がない場合は、自分自身のメソッドで処理します。)

ですので、一概に「やってはならない」とは言えないでしょう。
今回の様な例では不適切な利用方法だと思いますが。
ibara
常連さん
会議室デビュー日: 2002/11/15
投稿数: 26
投稿日時: 2005-12-29 13:56
引用:

かつのりさんの書き込み (2005-12-29 12:43) より:
フレームワーク等を利用したクラス設計を行う場合、
例外処理を上位クラスに委譲するために、
すべてthrows Exceptionでスローするという設計もあります。
(上位クラスに委譲する必要がない場合は、自分自身のメソッドで処理します。)

ですので、一概に「やってはならない」とは言えないでしょう。
今回の様な例では不適切な利用方法だと思いますが。


そうでしょうか?throws Exceptionとしなくてもすべての例外処理を上位に委譲することは可能ではないですか?どのようなケースでもthrows Exceptionという方法が不適切ではないケースはないと思います。このような実装を強要するフレームワークがあるのならばそのフレームワークに問題があるのではないでしょうか。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-12-29 21:20
引用:

どのようなケースでもthrows Exceptionという方法が不適切ではないケースはないと思います。このような実装を強要するフレームワークがあるのならばそのフレームワークに問題があるのではないでしょうか。


何個か例を挙げたいと思います。

StrutsのActionクラスのexecuteメソッドはthrows Exceptionとなっています。
これは、業務ロジックで発生した例外を上位クラス(呼び出し元)である、
RequestProcessorに渡す為ですが、RequestProcessorは例外の種類によって
適切にハンドルされエラー処理が行われます。

java.lang.reflect.Proxyと共に使用されるjava.lang.reflect.InvocationHandlerですが、
invokeメソッドはExceptionではありませんが、throws Throwableとなっています。
invokeメソッドで発生した例外処理はプロキシインスタンスに委譲され、
プロキシのインスタンスは対象の例外をラップして、java.lang.reflect.UndeclaredThrowableExceptionをスローします。

AccessController#doPrivilegedとPrivilegedExceptionActionの関係も同じですね。


引用:

そうでしょうか?throws Exceptionとしなくてもすべての例外処理を上位に委譲することは可能ではないですか?


例外をすべてRuntimeExecptionでラップしてスローされるということでしょうか?
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-12-30 00:54
コード:
public class SuperClass {
    public void hoge() throws Exception {
        ...
    }
}

public class SubClass extends SuperClass {
    @Override
    public void hoge() throws IOException {
        ...
    }
}


スーパークラスやインターフェイスが Exception を投げるように宣言していても、サブクラスは別の例外を投げるように宣言できます。なので、フレームワークが実装者に対して Exception を投げることを強要しているとは言えないのではないかと思います。
1

スキルアップ/キャリアアップ(JOB@IT)