2012-11-22 10 views
6

C#入門書では、何をするべきかわからない場合は例外をキャッチしないようにしています。 Javaでプログラミングをしているときにそのアドバイスを考えると、私は例外について何をすべきかわからないことがありますが、コンパイルエラーを避けるために、それをキャッチしたり、 "あいまいにする"ことを余儀なくされています。私はむしろ、throws節を持つメソッドを混乱させるつもりはないので、次のように例外を "RuntimeException"に "変換"することに頼っています。実際に「処理されていない」(適切に処理されていない)例外の多くのメソッドにthrows句を追加すると、冗長で気を散らすように思えます。次の悪いスタイルがありますか?そうであれば、これに対処するより良い方法は何ですか?致命的な例外を処理する

try { 
    thread.join(); 
} 
catch (InterruptedException e) { 
     Console.printwriter.format("%s\n", e.printStackTrace()); 
    throw new RuntimeException(); 
} 

編集:あなたはおそらく、いくつかの不要なthrows句で終わるコードの改正後:脇混乱から、浸透の例外を除いて、別の問題があります。私がそれらをきれいにするために知っている唯一の方法は、試行錯誤によるものです:それらを削除し、コンパイラが不平を言うかどうかを確認してください。明らかに、コードをきれいに保つことを望むなら、これは面倒です。

+0

。 – lifetimes

+0

合意。私は一般に、新しく定義された多くの例外を宣言していません。私は主にサードパーティとJavaの例外について懸念しています。 – H2ONaCl

+0

@ user1394965はい、あなたのコードは「常に」例外をスローするべきではありません。しかし、それは例外が可能かどうかということとはまったく異なる問題です。 IO操作やブロッキングメソッドを含む何かは、やむを得ない例外処理ではぎとられる可能性があります。 –

答えて

5

チェックされた例外と未チェックの例外の間のJavaの分割はsomewhat controversialです。

インターフェイスを制御する場合は、通常、署名にthrows句を追加するのが最善の方法です。

例外を処理できないが、チェックされた例外シグネチャのためにバブルアップすることができない状況にある場合、例外を再スローすることができる例外にラップすることがよくあります(多くの場合、RuntimeException)一般的なプラクティスです。

多くの場合、IOExceptionやSQLExceptionなどの別のチェック例外を使用することをお勧めします。しかし、それは常にオプションではありません。

しかし、あなたの例では、「原因」として、元の例外が含まれています。これは、例外を処理することができます誰かに延期することができますので、

throw new RuntimeException(e); 

また、これは、(ログの必要性を取り除くことが、すべての情報はまだそこにあります)。

1

例外の処理方法がわからない場合は、その例外をキャッチしないでください。したがって、メソッドで例外がスローされるため、実行時例外でない場合はthrows節が必要です。それらには何も問題はありません。

+0

@broiyanはい、私は通常の例外を扱っている質問の文脈で答えていました。 – Pablo

1

私はJoshua BlochのEffective Java 2nd Editionのアドバイスが好きです。抽象化(Item 61)に該当する例外をスローします。

つまり、あなたのメソッドの "浸透"を望む一連の例外に直面したときは、例外をメソッドに意味的に意味を持たせるものに再ラップする必要があるかどうかを検討します。

このようなアプローチでは、いくつかの下位レベルの例外を1つの上位レベルの例外に組み合わせることで、しばしば面白い副作用があります。

+0

それは良い考えです。 – H2ONaCl

+0

スローされた例外を単純化する利点と、あなたのコードベースを膨らませる何百ものカスタム例外を発明する利点のバランスをとっています。 –

1

良いプログラミングプラクティスでは、オブジェクトの内部状態を呼び出し側から隠す必要があり、少なくとも私の場合は例外が含まれているはずです。あなたはその例外の意味をあなたに見て、あなたのクラスの呼び出し側にその意味を表すExceptionを返すべきです。

フレームワークがすでにその意味で例外を提供している場合、たとえばIllegalArgumentExceptionの場合は、新しいオブジェクトをインスタンス化し、発生したことの説明がよく、ocurred例外をカプセル化する文字列を新しいIllegalArgumentException ( "引数Xは...のために無効です"、e); フレームワークに問題の記述的な例外がない場合は、独自の例外セットを作成する必要があります。私は通常、そのプロジェクト/パッケージ(それはExceptionまたはRuntimeExceptionを拡張する)に対する一般的な例外を作成し、その例外を派生させます。 たとえば、私は最近、私たちのサービスとアプリケーションモジュールで再利用される汎用リポジトリプロジェクトを作成し、データベースにアクセスしました。私がDBにアクセスするために使用していた呼び出し元を、例外から抽象化したいので、JPAのHibernate例外をカプセル化するためのいくつかの例外を作成しました。私はここのコードを持っていないが、それはのようなものだった。それに対処するより良い方法は、あなたは常に例外をスローする必要はありません方法でコードを書くことです

// implementation package 
public abstract class GenericRepository<K, E extends<K>> implements IRepository<K, E>{ 

    // constructors 

    public final void add(E entity){ 
     // some code 

     try{ 
      // code that can throw exceptions 
     } catch (EntityExistsException e) { 
      // some code 
      throw new EntityAlreadyExistsException(e); 
     } catch(RuntimeException e) { 
      // some code 
      throw new GenericRepositoryException("An unexpected exception occurred while manipulating the database", e); 
     } 
    } 

    // some other code 

} 


// exception package 
public final class EntityAlreadyExistsException extends GenericRepositoryException{ 

    public static final String GENERICMESSAGE = "The entity already exists on the table"; 

    public EntityAlreadyExistsException(Throwable cause){ 
     super(GENERICMESSAGE, cause); 
    } 

    // other constructors 

} 
関連する問題