web-dev-qa-db-ja.com

「throws」を使用したメソッド宣言で指定されていない例外をメソッドがスローするとどうなるか

「スロー」句を使用したことがないので、今日、メイトから、メソッド宣言でメソッドがスローする例外を指定する必要があると言われました。ただし、例外を使用せずに問題なく使用してきたので、実際に必要なのに、なぜ必要なのでしょうか。

20
bluehallu

Javaには、2種類の例外があります。チェック済み例外とチェックなし例外です。

未チェックの例外はRuntimeExceptionのサブクラスであり、throws宣言を追加する必要はありません。他のすべての例外は、try/catchステートメントまたはthrows宣言を使用して、メソッド本体で処理する必要があります。

未チェックの例外の例:IllegalArgumentExceptionは、メソッドが不正な引数で呼び出されたことを通知するために時々使用されます。投げる必要はありません。

チェック例外の例:Java.ioパッケージの一部のメソッドがスローする可能性があるIOException。 try/catchを使用するか、throws IOExceptionをメソッド宣言に追加して、例外処理をメソッド呼び出し元に委任します。

24
Andreas_D

メソッドがthrowsキーワードで宣言されている場合、そのメソッドを呼び出したい他のメソッドは、それをキャッチする準備をするか、それ自体が例外をスローすることを宣言する必要があります。

たとえば、アプリケーションを一時停止したい場合は、Thread.sleep(milliseconds);を呼び出す必要があります

しかし、このメソッドの宣言は、InterruptedExceptionをスローすることを示しています

宣言:

public static void sleep(long millis) throws InterruptedException

したがって、たとえばメインメソッドでそれを呼び出したい場合は、それをキャッチする必要があります。

public static void main(String args[]) {
    try {
        Thread.sleep(1000);
    } catch(InterruptedException ie) {
        System.out.println("Opps!");
    }
}

または、メソッドが例外をスローしていることも宣言します。

public static void main(String args[]) throws InterruptedException {
    Thread.sleep(1000);
}
13
Anton

checked例外があっても発生する可能性があります。そして時々それはロギングを壊すことができます。

ライブラリメソッドがこのトリックを使用して、RunnableをスローできるIOExceptionの実装を許可するとします。

class SneakyThrowTask implements Runnable {

    public void run() {
        throwSneakily(new IOException());
    }

    private static RuntimeException throwSneakily(Throwable ex) {
        return unsafeCastAndRethrow(ex);
    }

    @SuppressWarnings("unchecked")
    private static <X extends Throwable>X unsafeCastAndRethrow(Throwable ex) throws X {
        throw (X) ex;
    }

}

そして、あなたはそれをこのように呼びます:

public static void main(String[] args) {
    try {
        new SneakyThrowTask().run();
    } catch (RuntimeException ex) {
        LOGGER.log(ex);
    }
}

例外はログに記録されません。そしてそれはチェックされた例外なので、これを書くことはできません:

public static void main(String[] args) {
    try {
        new SneakyThrowTask().run();
    } catch (RuntimeException ex) {
        LOGGER.log(ex);
    } catch (IOException ex) {
        LOGGER.log(ex); // Error: unreachable code
    }
}
6
finnw
  1. メソッドがスローするチェック済み例外を宣言する必要があります。
  2. 「例外をスローする」と宣言すると、チェックされたすべての例外ではなくてもほとんどの例外がカバーされます
  3. 常にチェックされていないランタイム例外をスローすることができ、宣言する必要はありません。

チェックされた例外をスローしようとし、そのタイプをスローするようにメソッドを宣言していない場合、コードはコンパイルさえしません(今チェックしています)。

編集、それであなたが簡単なものを試してみたら

public static void main(String[] args) {
   throw new Exception("bad");
}

コンパイルエラーが発生します。

特に質問については、例外をスローするように宣言されているメソッドを呼び出す場合は、メソッドの呼び出しを試行またはキャッチするか、メソッドが例外をスローすることを宣言する必要があります。

4
hvgotcodes

throwsキーWordは、別のメソッドに例外をスローするために使用されます。

これは、ユーザーに対するハンドル例外を緩和します。なぜなら、すべての例外は、実行に使用されるメソッドで処理できるからです。

ほとんどの場合、これはメソッドであるため、ユーザーはメソッド内を探索する必要がありません。

また、発生する可能性のある例外を処理するためにキーワードforceをコンパイラーにスローします。

API開発者の場合、コードを記述すると例外が発生する可能性があるため、throwsキーワードを使用して、メソッドの実行時に例外を処理します。

3

Javaはキーワードをスローします

  • Java throwsキーワードは、例外を宣言するために使用されます。
  • throwsの後にはクラスが続きます。
  • チェックされた例外はthrowsで伝播できます。
  • 例外に関するメソッドの呼び出し元に情報を提供します。

throwsの例、

void m()throws ArithmeticException{  
    //method code  
}