[解決済み] IllegalArgumentExceptionはどのような場合にスローされるのですか?
質問
実行時例外処理なので、控えめにしたほうがいいのではと心配です。
標準的な使用例です。
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
しかし、それだと次のようなデザインを強いられるような気がします。
public void computeScore() throws MyPackageException {
try {
setPercentage(userInputPercent);
}
catch(IllegalArgumentException exc){
throw new MyPackageException(exc);
}
}
チェックされた例外に戻すため。
なるほど、でもそれで行こう。 悪い入力をすると、ランタイムエラーが発生します。 だからまず第一に、それは実は一律に実装するのがかなり難しいポリシーで、全く逆の変換をしなければならない可能性があるからです。
public void scanEmail(String emailStr, InputStream mime) {
try {
EmailAddress parsedAddress = EmailUtil.parse(emailStr);
}
catch(ParseException exc){
throw new IllegalArgumentException("bad email", exc);
}
}
さらに悪いことに、チェック中に
0 <= pct && pct <= 100
しかし、電子メールアドレスのような高度なデータ、あるいはデータベースと照合する必要のあるデータについては、そうではありません。
つまり、基本的に私が言いたいのは、「Security」の使用に関する意味のある一貫したポリシーが見当たらないということです。
IllegalArgumentException
. これは使うべきではなく、独自のチェックされた例外にこだわるべきと思われます。 これを投げる良いユースケースは何でしょうか?
解決方法は?
治療
IllegalArgumentException
として
前提条件
を確認し、設計方針を検討する。
パブリック・メソッドは、それ自身の前提条件を知っていると同時に、それを公的に文書化する必要があります。
この例は正しいということになりますね。
void setPercentage(int pct) {
if( pct < 0 || pct > 100) {
throw new IllegalArgumentException("bad percent");
}
}
EmailUtilが不透明の場合 つまり、前提条件をエンドユーザーに説明できない何らかの理由がある場合、チェックされた例外が正しいのです。この設計を修正したのが第2版です。
import com.someoneelse.EmailUtil;
public void scanEmail(String emailStr, InputStream mime) throws ParseException {
EmailAddress parsedAddress = EmailUtil.parseAddress(emailStr);
}
EmailUtilが透過的である場合
例えば、問題のクラスが所有するプライベート・メソッドである可能性があります。
IllegalArgumentException
は、その前提条件が関数のドキュメントに記述されている場合に限り、 正しいと言えます。これも正しいバージョンです。
/** @param String email An email with an address in the form [email protected]
* with no nested comments, periods or other nonsense.
*/
public String scanEmail(String email)
if (!addressIsProperlyFormatted(email)) {
throw new IllegalArgumentException("invalid address");
}
return parseEmail(emailAddr);
}
private String parseEmail(String emailS) {
// Assumes email is valid
boolean parsesJustFine = true;
// Parse logic
if (!parsesJustFine) {
// As a private method it is an internal error if address is improperly
// formatted. This is an internal error to the class implementation.
throw new AssertError("Internal error");
}
}
このデザインは、どっちでもいいんです。
-
前提条件を記述するのが面倒な場合、あるいはメールが有効かどうかわからないクライアントがこのクラスを使うことを想定している場合は
ParseException
. ここでのトップレベルのメソッドはscanEmail
これは、エンドユーザが未審査のメールを送信することを意図していることを示唆しているので、おそらく正しいでしょう。 -
関数のドキュメントに前提条件を記述することができ、クラスが無効な入力を意図しないため、プログラマエラーが表示される場合、次のように使用します。
IllegalArgumentException
. チェックはされませんが、このチェックは関数のドキュメントであるJavadocに移動し、クライアントはこのドキュメントを遵守することが期待されます。IllegalArgumentException
クライアントが自分の引数が違法であることを事前に知ることができないのは、間違っています。
IllegalStateExceptionに関する注意点
: これは、「このオブジェクトの内部状態(プライベートなインスタンス変数)が、このアクションを実行できない」ことを意味します。
IllegalArgumentException
クライアントコールがオブジェクトの状態に矛盾があることを知る術がない場合。チェックされた例外よりも優先される場合について、私は良い説明を持っていません。たとえば、2回初期化された場合や、データベース接続が回復しないまま失われた場合などがその例ですが、このような場合です。
関連
-
[解決済み] Java - JTextFieldが空かどうかを確認する
-
[解決済み] XX:MaxDirectMemorySizeの既定値
-
[解決済み] Java の文字列インデックスが範囲外です。0 [閉店]
-
[解決済み] Java: getInstanceとStaticの比較
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] JUnit 4のテストで、ある例外が投げられたことをどのように断言しますか?
-
[解決済み] ThreadLocal変数はいつ、どのように使用すればよいですか?
-
[解決済み] Pythonで悪い/不正な引数の組み合わせに対してどの例外を発生させるべきですか?
-
[解決済み] noexceptを本当に使うべきはいつですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Javaで拡張子なしのファイル名を取得する方法は?
-
[解決済み] javaで部分クラスを実装する方法
-
[解決済み] コレクションへの共有参照が見つかりました org.hibernate.HibernateException
-
[解決済み] java.util.concurrent.ExecutionException 例外をどのように処理しますか?
-
[解決済み] プロトコルハンドラの初期化に失敗しました。
-
[解決済み] ORA-01654: インデックスを拡張できません。
-
[解決済み] 午前0時からの時間を秒単位で取得する方法
-
[解決済み] アニメーションGIFの表示
-
[解決済み] タイプの安全性。アンチェック・キャスト
-
[解決済み] .lengthが解決できない、またはフィールドでない