throws宣言を追加せずに例外をスローする方法はありますか?


81

私は次のような状況にあります。

別の基本クラスを継承し、メソッドをオーバーライドするJavaクラスがあります。基本メソッドは例外をスローしないため、throws ...宣言はありません。

これで、自分のメソッドで例外をスローできるはずですが、どちらかを選択できます。

  • 例外を飲み込む
  • スロー宣言を追加する

最初のものは例外を黙って無視するため(ログを実行できます)、2番目のものはメソッドヘッダーが異なるためにコンパイラエラーを生成するため、どちらも満足のいくものではありません。

public class ChildClass extends BaseClass {

        @Override 
        public void SomeMethod() {
            throw new Exception("Something went wrong");
        }
}

回答:


99

本当に必要な場合は、宣言しなくても、チェックされていない例外をスローできます。未チェックの例外は拡張されRuntimeExceptionます。拡張するスローアブルErrorもチェックされていませんが、完全に処理できない問題(無効なバイトコードやメモリ不足など)にのみ使用する必要があります。

特定のケースとして、UncheckedIOExceptionJava8がラッピングと再スローのために追加されましたIOException


1
うまく機能します。例外は別のメソッドからのものであるため、RuntimeExceptionを再スローする必要がありますが、おかげでうまく機能します。
ユルゲン・Steinblock

42

ここにトリックがあります:

class Utils
{
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
    {
        throw (T) exception;
    }

    public static void throwException(Throwable exception)
    {
        Utils.<RuntimeException>throwException(exception, null);
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Utils.throwException(new Exception("This is an exception!"));
    }
}

これはどのように機能するのだろうか?調査を行いますが、役立つリソースはありますか?:-)
holmicz 2016年

TはRuntimeExceptionとして推測されます。ここに答えstackoverflow.com/questions/41380656/...こことstackoverflow.com/questions/31316581/...
seenimurugan

1
素晴らしいトリック!このトリックはラムダ式/ブロックにも適用でき、throws宣言なしでチェック例外メソッドをSAMインターフェイスに割り当てることができます。
JasonMing 2017

安全でないことに対処する必要がないという追加の超追加ボーナスがあります。
lscoughlin

なぜダミーパラメータが必要なのですか?また、これは一般的な方法なしで機能しますか?
Kiruahxh

28

3番目のオプションは、例外チェックをオプトアウトし(Standard API自体が時々行う必要があるように)、チェックされた例外をRuntimeException:でラップすることです。

throw new RuntimeException(originalException);

のより具体的なサブクラスを使用することをお勧めしますRuntimeException


10

純粋に参考までに、別の答えを追加したいだけです。

はい、クラスthrowsを使用して、宣言を追加せずにチェックされた例外をスローする方法がありますsun.misc.Unsafe。これについては、次のブログ投稿で説明されています。

宣言せずにメソッドからチェックされた例外をスローします

サンプルコード:

public void someMethod() {
  //throw a checked exception without adding a "throws"
  getUnsafe().throwException(new IOException());
}

private Unsafe getUnsafe() {
  try {
    Field field = Unsafe.class.getDeclaredField("theUnsafe");
    field.setAccessible(true);
    return (Unsafe) field.get(null);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

ただし、これはお勧めしません。他のいくつかの回答で概説されているように、チェックされていない例外でラップすることをお勧めします。


3
彼らがそのクラスを呼ぶのには理由がありUnsafeます。
OrangeDog 2010

4

未チェックの例外をスローしてみませんか?これを宣言する必要はありません。

2つの選択肢は

  • チェックされていない例外でチェックされた例外でラップします。
  • チェックされた例外をスローしていることをコンパイラに知らせないでください(例:Thread.currentThread()。stop(e);
  • Java 6では、例外が発生した場合に例外を再スローできfinal、コンパイラーは、キャッチした可能性のあるチェック済み例外を認識します。
  • Java 7では、例外が事実上最終的なものである場合、つまりコードで変更しない場合に、例外を再スローできます。

後者は、コードでチェック例外をスローし、呼び出し元のコードでそれをキャッチする場合に役立ちますが、その間のレイヤーは例外について何も知りません。


2番目の方法も興味深いです。しかし、現時点では、例外をラップすることはまさに私が必要としていることです。
ユルゲン・Steinblock


@OrangeDog、これを読んだので、現在のスレッドでstop()を使用することと、ラップされた例外をスローすることの違いを教えてください。;)
Peter Lawrey 2010

「次のメソッドは、動作上はJavaのthrow操作と同じですが、呼び出し元のメソッドがスローする可能性のあるすべてのチェック済み例外を宣言していることを保証するコンパイラーの試みを回避します」例外のラップはどのように改善されますか?
Peter Lawrey 2010

「スレッドを停止すると、ロックされているすべてのモニターのロックが解除されます。これらのモニターによって以前に保護されていたオブジェクトのいずれかが不整合な状態であった場合、他のスレッドはこれらのオブジェクトを不整合な状態で表示する可能性があります。[...]その他のチェックされていない例外[...]ユーザーは自分のプログラムが破損している可能性があるという警告はありません。」
OrangeDog 2010

4

はい、理由はありますが、使用できることはまったくお勧めしません:

Javaの安全でないパッケージ

getUnsafe().throwException(new IOException());

このメソッドはチェックされた例外をスローしますが、コードはそれをキャッチまたは再スローすることを強制されません。ランタイム例外と同じです。


2

チェックされた例外をインターセプトし、チェックされていない例外でラップする例を次に示します。

public void someMethod() {
   try {
      doEvil();
   }
   catch (IOException e)
   {
       throw new RuntimeException(e);
   }
}

-1

メソッドのtry-catchブロックをオーバーライドして例外をキャッチできます。その場合、throws-ステートメントを宣言する必要はありません。


2
確かに、しかしそれなら私は例外を飲み込むでしょう、それは私が達成したいものの正反対です;)
JürgenSteinblock

-1

RuntimeExceptionまたはRuntimeException自体から派生した任意の例外を使用できます

または

例外スローコードにtry-blockを使用し、そこで処理します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.