9

try/を使用するベスト プラクティスについて非常に基本的な質問がありcatchます。

次のような単純な関数 (DAO) があります。

public void addVehicle(Vehicle vehicle) {

    em.getTransaction().begin();
    em.persist(vehicle);
    em.getTransaction().commit();
}

Web サービス内で DAO 関数を使用する場合:

@WebMethod(operationName = "addVehicle")
public void addVehicle(Vehicle vehicle) {

    try {
        vehicleDAO.addVehicle(vehicle);
        System.out.print("Vehicle added");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

または、次のように DAO 関数内でtry/を使用することをお勧めします。catch

public void addVehicle(Vehicle vehicle) {

    try {
        em.getTransaction().begin();
        em.persist(vehicle);
        em.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
4

5 に答える 5

12

そのための完璧なルールはありません。

必要に応じてできるだけ早く例外をキャッチすると、コードはより明確になり、複雑さが軽減されます。それが発生
したときに誰がアクションを実行する必要があるかを考える必要があります。これにより、メソッド内で実行するか (addVehicle)、または呼び出し元がアクションを実行する必要があるかが決まります。Exceptioncatchthrowcatch

例えば:

 public void addVehicle(Vehicle vehicle) throws SQLException{
        em.getTransaction().begin();
        em.persist(vehicle);
        em.getTransaction().commit();
 }

この例では、呼び出し元がキャッチする必要があります。
さらに、いくつかの状況でのみ、Exceptionまたはの代わりにRunTimeExceptionその特定の例外をキャッチする必要があります。IOExceptionException

コードのどこかに、意味のある「最後の防衛線」が必要になりますcatch (Exception ex).。これは、発生してはならないエラーを処理するために必要です。

于 2013-01-08T19:11:50.117 に答える
5

特定の種類の例外をどこで処理するかを決定するときの最良の経験則は、コードの細部を見るのをやめ、一歩下がってプログラムのロジックについて推論し、次のことを考慮することです。

  • 例外は、プログラムの現在の操作では回復できないものですか? はいの場合、その操作の最上位レベルに例外を配置して、続行しないようにすることだけが理にかなっています。
  • あなたのプログラムがその特定の例外を回避できる場合 (おそらくあきらめる前に別のことを試みることによって)、ネストされた関数の各層 (最上位から開始) を取り、そのたびに次のことを自問してください:コードのある行の実行中に例外が発生した場合この関数では、この関数が継続することは理にかなっていますか? 答えが「はい」である限り、より深いレベルに移動します。答えが「いいえ」である場合、その例外のハンドラーを配置するのに最適な場所である可能性があります。
  • 前のものの代わりに、例外が発生した場合のプログラムの代替の「攻撃計画」を決めることができます。次に、その例外を発生させるコード行に移動し、自問してください。この関数には、考えている回避策を実行するのに十分なコンテキスト情報がありますか? 答えが「いいえ」である限り、呼び出し元の関数に移動します。答えが「はい」になったらすぐに、そこに例外ハンドラを配置することを検討してください。

そうは言っても、合理的に特殊化された例外のみをキャッチし、その時点で本当に予測できなかった種類の例外のためにのみ予約し、最上位レベルでのみ、他のすべての可能なブロックの後にcatch(Exception ex)のみ、最後の手段として構造を保持する必要があります書くこと。(これは例のポイントではないとあなたが言ったことは知っていますが、私たちはそれに取り組んでいるので、この答えをより完全にするために言及する必要があると思いました。)catch

于 2013-01-08T20:04:23.850 に答える
0

処理したい例外のみをキャッチする必要があります。最上位の例外ハンドラーを含めて、未処理の例外をエンド ユーザーにとってある程度役立つものに変えることができます。

の代わりにe.printStackTrace();、適切な例外メッセージを返すようにしてください。

例外処理の詳細については、こちらをご覧ください

ここでは、例外処理についてさらに説明します

于 2013-01-08T19:11:43.883 に答える
0

私の知る限り、ベストプラクティスは次のようになります。

public void addVehicle(Vehicle vehicle) {
        em.getTransaction().begin();
        try {
            em.persist(vehicle);
            em.getTransaction().commit();
        } catch (Exception e) {
            if (em.getTransaction().isActive()) {
                try {
                   em.getTransaction().rollback();
                } catch (Exception e) {
                   // Log rollback failure or something
                }
            }
            throw new RuntimeException(e);
        } 
}
于 2013-01-08T19:15:35.803 に答える
0

両方を使用してください。唯一の理由は、 catchRuntimeExceptionまたは evenを使用することThrowableです。この種の例外は通常、基盤となるフレームワークによってスローされるためです。再度スローする前に、ロギング、スタック トレースの出力などのアクションを実行する場合は、この種の例外を正確にキャッチする必要があります。そうしないと、例外の原因がなくなる可能性があります。

@Transactional
public void addVehicle(Vehicle vehicle) {
  try {
    //do whatever with session
  } catch (RuntimeException e) {
    e.printStackTrace();
    throw new Exception(e);
  }
}
于 2013-01-08T19:11:27.390 に答える