2012-06-13 10 views
17

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

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

もっと良い方法がありますか?または、UnsatisfiedLinkErrorをここで受け入れていますか?

+5

ここで適切なコンビネーションについては考えていませんが、ファイルが存在するかどうかをテストする前に試してみることができます... ['new File(" path/helloworld.dll ").exists()'](http:// docs。 oracle.com/javase/7/docs/api/java/io/File.html#exists%28%29)....(編集:間違った提案、私はコードを誤読しました) –

+5

私はそれを許容可能な回避策と考えています。 –

+0

@Slanec 'java.library.path'ディレクトリ内のすべてのディレクトリを検索する必要があります。 –

答えて

16

技術的に問題を解決する方法をアドバイスする以外に、まずは「悪い習慣」と考えられる理由を説明します。

まず、Errorクラスが何であるかを明確にして始めましょう。


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

Throwableクラスを継承するクラスは、ExceptionErrorの2つです。これら2つの違いは、彼らのドキュメンテーションで説明されています。

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

Source

クラス例外とそのサブクラスは、は、合理的なアプリケーション がキャッチされる可能性のある状態を示しているとのThrowable の形をしています。

Source


。上述のように、エラーと例外は、それらの異なる起源から分離されています。 Errorは通常、問題があることを示します。 アプリケーションはから回復できません。したがって、彼らは捕まえるべきではありません。

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


だから、今、あなたがから回復することができますのみキャッチ例外やエラーのものと理解していること、あなたの質問への答えは明確にする必要があります。

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


私はarticle on my Blogで上記(詳細および例)といくつかの拡張情報をカバーしました。

+0

このパラダイムに違反しなければならなかったのは、例外を指定しなかったクラスから通常のエラーをスローする必要があったときでした。だから、私は 'RuntimeException'から派生して、言語の必要条件を熟考しました。それでもこれを行うにはもっと良い方法があるといいですね。 – djechlin

+0

アプリケーションがエラーから回復できない場合は、それを捕まえることがさらに悪くないのですか? – simon

+0

@imonもしあなたが本当にエラーから回復できないなら、それを捕まえるときに何をするつもりですか?アプリケーションがもはや動かない場合、なぜそれを稼働させ続けるのですか? –

0

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

+0

チェックの後、ロードの前にライブラリが削除される可能性があるので、tryキャッチはおそらく必要です。 –

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は本当に悪いの失敗ではなく、適切な回避策があるかどうか、実際にも、故障ではありません回復可能な「障害」のためのものです。障害を処理するために設計されたシステムに、システムを複数の方法で構成する能力に過負荷をかけないでください。

0

非常に特殊な場合にのみ、エラーを検出する必要があります。あなたが他のすべての可能性を模索している場合にのみ、キャッチとエラー。私はLukas Knuthが言ったことすべてに完全に同意します。しかし、私は1つの小さな追加があります。 あらゆる種類のエラーをキャッチする場合は、できる限り狭い範囲からエラーを捕捉するようにしてください。また、可能であれば、エラーを捕捉するメソッドがfinalとして宣言されていることを確認してください。その理由は、エラーをキャッチすると、通常は非常に不安定なプログラムにつながる可能性があるからです。後で他のメソッドを呼び出すために拡張されたメソッドでエラーをキャッチし、これらのすべての基礎となるメソッドは、上にあるcatchによって(意図せずに)キャッチされたエラーを持つようになると考えてください。

エラーを捕捉する必要がある場合は、狭く制御されたフェイズで行います。

関連する問題