4

RuntimeException非例外をキャッチする必要性をJavaで取り除く可能性はありますか? 多分コンパイラフラグ?

キャッチが促進される理由はわかっていますが、要件を強制するシンプルでストレートなツールを実行したいと考えています。そのため、何か問題が発生した可能性がある場合、追いつくのは好きではありませんが、意味のある例外でクラッシュしてアプリケーションを終了します。通常、これは次のようになります。

try {
     connection.close();
} catch (IOException e) {
    throw new RuntimeException(e);
}   

これにより、4 行のコードがごちゃごちゃになり、RuntimeExceptionエラー出力のラッピングがごちゃごちゃになります。場合によっては、何かを大きなブロックで囲むように人々を動機付けることさえありtry ... catch (Throwable ..)ます。これが、最愛の「不明なエラーが発生しました」アラート ボックスの原因である可能性があります...

4

6 に答える 6

3

ブロックthrowsを回避するために、メソッドプロトタイプでキーワードを使用できます。try-catchこれは、発生した例外を処理するコードで catch ブロックが指定されていない場合、アプリケーションを停止する JVM のデフォルト例外ハンドラーに例外をスローします。

于 2011-04-25T13:26:50.300 に答える
3

例外を一目見ただけでアプリケーションをクラッシュさせることは、非常に悪い習慣です。特に、一部の作業が保存されておらず、アプリケーションが実行を終了する前に解放してクリーンアップする必要があるリソースをアプリケーションが使用している場合。いくつかの非常に人気のあるソフトウェアはそれを行っていました...そして問題を「修正」する代わりに、アプリケーションの再起動時にデータ回復機能を導入しました。しかし、これは良いソフトウェア エンジニアリングではありません。

少なくとも、最初の例外/エラーが発生したときにアプリケーションがクラッシュすることはなく、意味のあるメッセージで回復する必要があります。RuntimeExceptionすべてを a (または)でラップするだけThrowableで、特に何もしないのは面倒です。

1) 回避策、および 2) この状況を処理するためのより良い方法があるため、Java はどのような種類のフラグもサポートしていません。例えば ​​:

1. 呼び出し元のメソッドで例外を処理する

throwsメソッド宣言にキーワードをメソッドまで追加できますstatic public void main。例外を処理しないと、最終的にスタックトレースでアプリケーションがクラッシュします。

class Foo {
   public void someMethod(....) throws IllegalArgumentException, IOException {
      ...
   }

   static public void main(String...args) throws Throwable {
      new Foo().someMethod();
   } 
}

この方法は回復手段を提供せず、おそらくユーザーを不幸にします (アプリケーションをコンソールから実行した場合は意味のない大量の stachtrace が表示され、ショートカットまたは GUI から起動した場合はまったく何も表示されません)。また、取得したリソースがある場合、例外が発生したときにそれらをクリーンアップできません。少なくとも、上記の例外をスローする前に何かを出力するmain必要があります。catch (Throwable e)何かのようなもの :

class Foo {
   public void someMethod(....) throws IllegalArgumentException, IOException {
      ...
   }

   static public void main(String...args) {
      try {
         new Foo().someMethod();
      } catch (...) {
         // output or log exception here and, optionally, cleanup and exit
      }
   } 
}

**編集**

次のシナリオを考えてみましょう: プログラムがデータを処理するためにリソースを初期化し、処理中に実行時例外 (またはエラー) が発生し、アプリケーションがクラッシュしますが、リソースは解放または解放されません。ただし、Javaではこれを行うことができます

public E doSomething() throws RuntimeException {
   // declare a bunch of resources

   try {
      // process resources with unchecked exceptions
   } finally {
      // free resources
   }

   // return some result
}

エラーまたは成功時にメソッドをきれいに終了し、おそらく「後世」の実行時エラーをログに記録します。

2. エラーをログに記録し、意味のある値を返す

ロギングは非常に優れた方法です。全体をクラッシュさせずに操作を実行できなかったことを伝えるメッセージをユーザーに表示し、ユーザーが何をどこで行っていたかの痕跡を示すことができます。単純なロギング システムは次のようになります。

class Foo {
   static private final Logger LOG = Logger.getLogger(Foo.class.getName());

   public boolean doSomethingImpl(...) {
      boolean result = true;
      try {
        ...
      } catch (SomeException e) {
         LOG.log(Level.SEVERE, "meaningful message why method could not do something!", e);
         result = false;
      }
      return result;
   }

   public void doSomething() {
      if (!doSomethingImpl(...)) {
          // handle failure here
      }
   }
}

デフォルトでは、Loggerはすべてをerr出力ストリームに出力しますが、独自のハンドラを追加できます:

// loggers are singletons, so you can retrieve any logger at anytime from
// anywhere, as long as you know the logger's name
Logger logger = Logger.getLogger(Foo.class.getName());

logger.setUseParentHandlers(false);  // disable output to err
logger.addHandler(new MyHandler());  // MyHandler extends java.util.logging.Handler

Java にはすでにいくつかのデフォルトのロギング ハンドラが付属しており、そのうちの 1 つはfile に書き込みます

于 2011-04-25T13:42:21.147 に答える
1

「スロー」を使用してエラーを回避します..しかし、それは良いプログラミングの練習にはなりません

于 2011-04-25T13:36:55.360 に答える
1

JVM でこれを回避する方法はないと思います。最善の策は、メソッドに例外を再スローさせることです。これにより、コード内の「混乱」が解消され、メイン プログラムに例外がスローされます。これにより、プログラムの先頭までエラーが伝播されます。

ただし、例外が実際に発生する場所は、何が発生したか (つまり、この特定の IOException が発生したときに正確に何をしていたか) をユーザーに知らせるのに適した場所であることに注意してください。すべてのエラーが単純にトップ レベルまで伝搬されると、この解決策が失われます。

于 2011-04-25T13:29:36.773 に答える
1

例外をレベルアップする能力があります。これが例です

public class Foo {
    public Foo() {
        super();
    }
    public void disconnect(connection) throws IOException {
        connection.close();
    }
}
于 2011-04-25T13:31:20.453 に答える
1

Java で、RuntimeException 以外の例外をキャッチする必要性を取り除く可能性はありますか?

チェックされた例外の場合、例外をキャッチするか、メソッド ヘッダーで例外をスローとして宣言するかを選択できます。

多分コンパイラフラグ?

いいえ。これを緩和するコンパイラ フラグはありません。これは、言語設計の基本的な部分です。コンパイラ スイッチを使用してチェック例外規則を緩和すると、ライブラリの相互運用性に深刻な問題が発生する可能性があります。

于 2011-04-25T15:22:12.587 に答える