web-dev-qa-db-ja.com

「throws IOException」の使用が必須である理由

ファイルがローカルファイルシステム内にある場合、外部ファイル操作の処理中にmainメソッドで「throws IOException」を使用することが必須である理由.

8
Mayur Patel

throws IOException.の使用は必ずしも必須ではありませんが、例外をスローする可能性のあるメソッドを呼び出す場合は、どちらかが必要です。

  1. それをキャッチする、または
  2. 再スローすることを宣言します。

二つ目はあなたがやっていることです。もう1つは、多くの場合推奨される手法ですが、自分で例外をキャッチして処理することです。

public static void main(String[] argv) {
    try {
        FileReader f = new FileReader("foo.txt");
        // ... more
    } catch (IOException ioe) {
        System.out.println("Trouble reading from the file: " + ioe.getMessage());
    } 
}
19

Throws IOExceptionをメイン関数に追加することは必須ではないかもしれませんが、例外について何かをすることは必須です。ファイルio、ネットワークio、またはその他の(?)ioを実行しているときに、問題が発生する可能性があります。ファイルが存在しない可能性があります。ディスクの不良セクターにある可能性があります。ネットワークが途中でクラッシュする可能性があります(ディスクがローカルディスクでない場合、ネットワークまたはファイルioに問題になる可能性があります).

IOExceptionについて何かを行う必要があるのは、それがチェック例外であるためです。チェックされた例外をスローするコンストラクターまたは関数を呼び出す場合、それをキャッチして適切なアクションを実行することにより、それを処理する必要があります。または、例外について知っていることをコンパイラに伝える必要がありますが、それについては何もする予定はありません。その場合は、throws IOExceptionyour関数定義。

別のタイプの例外、チェックされていない例外があります(それらはすべてRuntimeExceptionを拡張するため、ランタイム例外と呼ばれることもあります)。未チェックの例外は潜在的な実行時の問題であると想定されていました。例えばNullPointerException(NPE)、実行時条件が原因のNPEの例は、オブジェクトを返すと予想される何かがNULLを返し、その上でメソッドを呼び出そうとした場合です。それは少なくとも理論です。

つまり、ランタイム例外は予期しないランタイム問題のためのものであり、それがなぜIOExceptionでないのか、ランタイム例外なのです。それは私がフレーキングディスクが失敗するか、またはスケネクタディのバックホウオペレーターが海岸の半分を取り出すことを計画したのとは異なります。 大声で叫ぶためにも私はそれを知りたいのです!誰かがハレルヤをくれます、ああ、そうです!

私はIO関連する作業をJavaで大量に実行しており、throws IOException 、なぜなら、一般的に、低レベルのコードはコンテキストが何であるかまったくわからないため、低レベルでIOExceptionを処理しようとすることは悪い考えです。あなたが何をしようとしているのか、そしてそれはそれらの例外があなたが達成しようとしていることにコンテキストがあるコードにまで泡立つことができるはずです。

ああ、ところで、私は、IOExceptionがランタイム例外ではないのにNPEのようなものはなぜなのかを知りたいと述べました。はい、それは実行時の状態ですが、IO(ディスク、ネットワーク、その他))はあなたが思っているよりもはるかに信頼性が低いです。ディスクが信頼できると確信している場合は、 SunがZFSを発明した理由。そして、そのネットワークが信頼できると思う場合は、マーケティングコンテンツが15,000のWindowsベースのキオスクに確実にダウンロードされるようにし、粗末な3Dパーティーネットワークを介して、顧客がそのようなジャンクイメージを見ないようにしてください。ネットワークの問題が原因で壊れていました(sha-1ハッシュサムの子と言えますか?できると思いました)。

私はこれでどこかに行きます。約束します。

IOExceptionがチェック済み例外である理由は、IOは信頼できないためです( Fallacies of Distributed Computing の誤り#1を見てください)。 )一般に、コードからNPEバグを取り除くことができるはずですが、IOは別の獣であり、信頼性がありません。その意図は、あなたに考えさせることでした。 Fallacies of Distributed Computing の著者の1人がJames Goslingであると述べましたか?James GoslingはJavaの父親と同じ人物ですか?ええ、それは私の理論です少なくとも、どちらか、またはそれはすべて、単に大きな愚かな間違いでした。初期のJavaライブラリには、多くの誤りがあります。

チェックされた例外の有用性については多くの議論がありましたが、時間が経つにつれ、彼らは努力するだけの価値はないと言っている人々に同意するようになりました。宣言されている例外は、ラップして適切な実行時例外を再スローします(たとえば、 lil friend !に挨拶します)。これにもかかわらず、私はIOExceptionを台無しにしません。賢明なことは、痛みを抱えて生きることです。

ああ、そして簡単に言えば、1つのコードがすべてpublic static void main(String [])に収まるため、IOException関数がスローされますか?正しい答えは、おそらく例外をバブルアウトさせ、ランタイムがコードを実行しようとしている貧しい人にそれを報告させることです。

ありがとう、おやすみなさい。

19
Bill

私の知る限り、それは必須ではありません。

例外を処理するか、処理しません。

例外を処理する場合はtry {...} catch(IOException e) {...}を配置する必要がありますが、処理しない場合は、現在のメソッドでthrows IOExceptionを宣言するだけです。

3

IOExceptionをスローすることはまったく必須ではありません。

Try and catchを使用する必要があります...役立つコードスニペットを以下に示します。

Scanner fileScanner = null;
        try
        {
            fileScanner = new Scanner(new File("YOUR FILE PATH"));
            while(fileScanner .hasNextLine())
            {
                String eachLine= scanner.nextLine();
                String[] wordsFromFile = eachLine.split("\\W");
            }
        }
        catch(FileNotFoundException e)
        {
            System.err.println("Cannot find the file");
        }
        finally
        {
            if(scanner!= null)
                scanner.close();
        }
1
Vince