27

java.lang.Errorキャッチは悪い習慣だと聞いたことがあります。現在、PATH にあることが保証されていない .dll をロードしています。そうでない場合は、ユーザーが構成した場所に切り替えたいと考えています。

try {
    System.loadLibrary("HelloWorld");
} catch(UnsatisfiedLinkError ule){
    System.load("C:/libraries/HelloWorld.dll");
}

これを行うより良い方法はありますか?または、ここでキャッチするUnsatisfiedLinkErrorことは許容されますか?

4

4 に答える 4

39

問題を技術的に克服する方法についてアドバイスする以外に、そもそもなぜそれが「悪い習慣」と見なされるのかを説明したいと思います。

Errorクラスとは何かを明確にすることから始めましょう。


Java では、エラーと例外 (主なタイプ) がスローされます。上記のいずれかをスローするには、throwキーワードを使用します。基本を拡張するすべてのクラスをjava.lang.Throwableスローできます。

基本クラスから継承する 2 つのクラスがありますThrowable:ExceptionError. これら 2 つの違いは、ドキュメントで説明されています。

Errorは、 Throwableのサブクラスであり、合理的なアプリケーションがキャッチしようとすべきではない重大な問題を示しますこのようなエラーのほとんどは異常な状態です。[...]

ソース

クラスExceptionとそのサブクラスは、適切なアプリケーション キャッチする可能性がある条件 を示すThrowableの形式です。

ソース


上で説明したように、エラーと例外は発生源が異なるため分離されています。はError通常、アプリケーションが回復できない問題を示します。したがって、彼らを捕まえてはいけません。

同じことが a にも当てはまりますがRuntimeException、高レベルのレイヤー (メソッドなど) の問題を示すために使用されます。Errorは低レベルの問題 (ランタイムなど) を示します。


したがって、回復できる例外とエラーのみをキャッチする必要があることを理解したので、質問への答えは明らかです。

UnsatisfiedLinkErrorはい、アプリケーションはそれから回復できるため、をキャッチすることは完全に合理的です。


上記の内容 (詳細と例を示します) といくつかの拡張情報については、私のブログ の記事で説明しました。

于 2012-06-13T16:01:08.207 に答える
2

非常に特殊なケースでのみエラーをキャッチする必要があります。他のすべての可能性を調査した場合にのみ、キャッチ アンド エラーを実行してください。ルーカス・クヌースが言ったことすべてに完全に同意します。しかし、私は1つの小さな追加があります。何らかのエラーをキャッチする場合は、できるだけ狭い範囲からエラーをキャッチするようにしてください。また、可能であれば、エラーをキャッチするメソッドが final として宣言されていることを確認してください。その理由は、通常、エラーをキャッチすると、非常に不安定なプログラムが発生する可能性があるためです。後で他のメソッドを呼び出すように拡張されたメソッドでエラーをキャッチしたとします。これらの基になるメソッドはすべて、上にある catch によって (意図せずに) エラーがキャッチされることになります。

エラーをキャッチする必要がある場合は、狭く制御された方法で行います。

于 2014-09-18T09:36:19.747 に答える
0

loadLibrary は findLibrary() を呼び出しますが、これは役に立ちますが、保護されています。最善の策は、ClassLoader を拡張する独自のクラスを作成することです。クラスローダーには、ライブラリへのパスを返す、またはライブラリが存在しない場合は null を返す、findLibrary() という保護されたメソッドがあります。そうすれば、エラーをキャッチする代わりに null をチェックできます。これが実際に「より良い」かどうかはわかりませんが、try catch の必要がなくなります。

于 2012-06-13T14:58:54.080 に答える
0

防御的にコーディングしていて、問題から回復できる場合、それは Java ではありませんError。そのような問題が発生する可能性が非常に低い場合は、サブクラスを作成し、それExceptionをスローしてキャッチします。Exceptionそのような問題が発生する可能性がある場合は、 ;をスローすることさえすべきではありません。ただし、通常のコード フローの一部にする必要があります。

try {
  if (config.hasCustomDLL()) {
    System.load(config.getCustomDLL());
  } else {
    System.loadLibrary(Config.DEFAULT_DLL);
  }
} catch (UnstatisfiedLinkError e) {
  System.out.println("Error loading DLL: " + e);
}

Errors適切な回避策がある場合、実際には障害でさえない回復可能な「障害」ではなく、本当に悪い障害を対象としています。障害を処理するように設計されたシステムに、システムを複数の方法で構成する能力に相当するものを過負荷にしないでください。

于 2012-06-13T16:12:06.423 に答える