web-dev-qa-db-ja.com

関数を呼び出すときに「例外をスローする」必要があるのはなぜですか?

class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

show2()show3()、およびmain()のメソッドが

未報告の例外キャッチするか、スローするように宣言する必要がある例外

これらのメソッドからthrows Exceptionを削除すると?

84
nr5

Javaでは、ご存知かもしれませんが、例外は2つに分類できます。1つはthrows句を必要とするもので、もう1つは指定しない場合は処理する必要があります。ここで、次の図を参照してください。

enter image description here

Javaでは、Throwableクラスを拡張するものなら何でもスローできます。ただし、すべてのクラスにthrows句を指定する必要はありません。具体的には、ErrorまたはRuntimeException、あるいはこれら2つのサブクラスのいずれかであるクラス。あなたの場合、ExceptionErrorまたはRuntimeExceptionのサブクラスではありません。そのため、チェック例外であり、throws句で指定する必要があります(その特定の例外を処理しない場合)。それがthrows句が必要な理由です。


Javaチュートリアル から:

例外は、プログラムの実行中に発生するイベントであり、プログラムの命令の通常のフローを中断します。

さて、ご存知のように、例外はチェック済みと未チェックの2つに分類されます。なぜこれらの分類ですか?

チェックされた例外:これらは、プログラムの実行中に回復できる問題を表すために使用されます。それらは通常、プログラマーのせいではありません。たとえば、ユーザーが指定したファイルが読めない、使用可能なネットワーク接続がないなど。これらのすべての場合、プログラムを終了する必要はなく、代わりにユーザーに警告するなどのアクションを実行したり、フォールバックしたりできます。メカニズム(ネットワークが利用できない場合のオフライン作業など)など.

未チェックの例外:これらもまた、エラーとRuntimeExceptionsの2つに分けることができます。それらがチェックされない理由の1つは、それらの数が非常に多く、それらすべてを処理するために必要なため、プログラムが混乱し、その明瞭さが低下することです。他の理由は次のとおりです。

  • 実行時例外:これらは通常、プログラマーによる障害のために発生します。たとえば、ゼロ除算のArithmeticExceptionが発生した場合、またはArrayIndexOutOfBoundsExceptionが発生した場合、コーディングに十分な注意が払われていないためです。これらは通常、プログラムロジックのエラーが原因で発生します。そのため、プログラムを実稼働モードにする前にクリアする必要があります。プログラマーが開発およびテスト時にそれを解決できるように、プログラムは発生したときに失敗する必要があるという意味でチェックされていません。

  • エラー:エラーは、通常プログラムが回復できない状況です。たとえば、StackOverflowErrorが発生した場合、プログラムの関数呼び出しスタックのサイズを増やすなど、プログラムは多くのことを実行できません。または、OutOfMemoryErrorが発生した場合、プログラムで使用可能なRAMの量を増やすことはできません。そのような場合は、プログラムを終了することをお勧めします。そのため、それらはチェックされません。

詳細については、以下を参照してください。

128
Jomoos

Javaでは、すべての例外を処理または宣言する必要があります。 try/catchブロックを使用して例外を処理していない場合は、メソッドのシグネチャで宣言する必要があります。

例えば:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

次のように書く必要があります。

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

このようにして、メソッド宣言の「例外をスロー」宣言を取り除くことができます。

22
jebar8

Exceptionはチェック済み例外クラスです。したがって、throws Exceptionを宣言するメソッドを呼び出すコードは、それを処理または宣言する必要があります。

3
Taymon

throws Exception宣言は、予想されるが避けられない理由で例外をスローする可能性のあるメソッドを追跡する自動化された方法です。宣言は、通常、throws IOExceptionthrows IOException, MyExceptionなど、スローされる可能性のある例外のタイプについて特定です。

ゼロ除算や境界外のインデックスなど、プログラムを実行する前に予期していなかったことが原因で予期せず停止し、例外を報告するコードを作成したか、最終的に作成します。メソッドはエラーを予期していなかったため、「キャッチ」できず、try catch句で処理できませんでした。メソッドの疑いを持たないユーザーもこの可能性を知らず、ユーザーのプログラムも停止します。

特定の種類のエラーが発生する可能性があることをプログラマが知っているが、メソッドの外部でこれらの例外を処理したい場合、メソッドは1つ以上の種類の例外を処理する代わりに呼び出し側メソッドに「スロー」できます。プログラマーがメソッドが例外をスローすることを宣言しなかった場合(またはJavaに宣言する能力がない場合)、コンパイラーはそれを知ることができず、将来のユーザー次第ですメソッドがスローする可能性のある例外を把握し、キャッチして処理するメソッド。プログラムは多くの異なるプログラムによって記述されたメソッドの多くのレイヤーを持つことができるため、どのメソッドが例外をスローする可能性があるかを追跡することが困難(不可能)になります。

Javaには例外を宣言する機能がありますが、未処理および未宣言の例外を持つ新しいメソッドを記述することができ、Javaはそれをコンパイルし、実行して最高の結果を期待できます。 。 Javaができないことは、メソッドで宣言された例外を処理するか宣言しない限り、例外をスローすると宣言されたメソッドを使用する場合、新しいメソッドをコンパイルすることです同じ例外をスローするメソッド、または複数の例外がある場合は、一部を処理して残りをスローできます。

プログラマーがメソッドが特定のタイプの例外をスローすることを宣言するとき、それはメソッドを使用している他のプログラマーに例外が可能であることを警告する自動化された方法です。プログラマーは、同じ例外をスローするように呼び出しメソッドを宣言することにより、例外を処理するか、警告を渡すかを決定できます。コンパイラはこの新しいメソッドで例外が発生する可能性があると警告されているため、新しいメソッドの将来の呼び出し元が例外を処理するか、それを宣言してどちらか一方を強制するかどうかを自動的に確認できます。

このタイプのソリューションの良い点は、コンパイラがError: Unhandled exception type Java.io.IOExceptionをレポートするときに、例外をスローするように宣言されたメソッドのファイル番号と行番号を提供することです。その後、単純に降圧を渡し、メソッドを「IOExceptionをスローする」ことを宣言することを選択できます。これはmainメソッドまで実行でき、プログラムが停止して例外をユーザーに報告します。ただし、例外をキャッチし、何が発生したのか、どのように修正するのかをユーザーに説明するなど、ナイスな方法で対処する方が適切です。メソッドが例外をキャッチして処理すると、例外を宣言する必要がなくなります。バックはいわばそこに止まります。

3
dansalmo
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

プログラムのわずかな変更のみ。主な問題に関して多くの人が誤解しているように思われますが、例外をスローするときはいつでもそれを処理する必要があり、同じ場所では必要ありません(たとえば、プログラムのshow1,2,3メソッド)が、最初は呼び出し元のメソッドである必要があります「メイン」内。 1つのWordには「スロー」があり、例外が発生する同じメソッドでなくても「キャッチ/トライ」が必要です。

0
tawess

現在のメソッドのシグネチャでthrowsディレクティブを宣言して例外を伝播する場合は、例外を処理するために行または呼び出しスタックのどこかでtry/catchコンストラクトを使用する必要があります。

0
Beaumont Muni
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Show()メソッドにはチェックされた例外があるため、そのメソッドでは処理されないため、例外を伝播するためにthrowsキーワードを使用します。

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Show2()メソッドでshow()メソッドを使用しており、少なくとも例外を伝播しているため、ここで処理する必要があります。ここで例外を処理していない場合は、throwsキーワードを使用しています。そのため、メソッドシグネチャでthrowsキーワードを使用する理由です。

0
Aditya