6

これが私たち全員が書いたコードの一部です:

    public CustomerTO getCustomerByCustDel(final String cust、final int del)
            SQLExceptionをスローします{
        最終的なPreparedStatementクエリ=getFetchByCustDel();
        ResultSetレコード=null;
        試す {
            query.setString(1、cust);
            query.setInt(2、del);
            records = query.executeQuery();

            this.getCustomer(records);を返します。
        } ついに {
            if(records!= null){
                records.close();
            }
            query.close();
        }
    }

'finally'ブロックを省略すると、データベースリソースがぶら下がったままになります。これは、明らかに潜在的な問題です。ただし、ここで行ったことを実行した場合(** try **ブロックの外側でResultSetをnullに設定してから、ブロック内の目的の値に設定した場合)、PMDは「DD異常」を報告します。ドキュメントでは、DDの異常は次のように説明されています。

DataflowAnomalyAnalysis:データフロー分析は、ローカル定義、未定義、およびデータフロー上のさまざまなパス上の変数への参照を追跡します。これらの情報から、さまざまな問題を見つけることができます。[...] DD-異常:最近定義された変数が再定義されました。これは不吉ですが、バグである必要はありません。

値を設定せずにブロックの外でResultSetを宣言すると、if(records!= null)テストを実行したときに、「変数が初期化されていない可能性があります」というエラーが正しく発生します。

さて、私の意見では、ここでの私の使用はバグではありません。しかし、PMD警告をトリガーしないクリーンに書き換える方法はありますか?URとDUの異常を特定することは実際に役立つので、PMDのDataFlowAnomalyAnalysisルールを特に無効にしたくありません。しかし、これらのDDの異常により、私はもっと良いことをしているのではないかと思うようになります。これを行うためのより良い方法がない場合は、混乱することになります(PMDルールを書き直すことができるかどうかを確認する必要があります)。

4

2 に答える 2

2

私はこれがより明確だと思います:

PreparedStatement query = getFetchByCustDel();
try {
    query.setString(1, cust);
    query.setInt(2, del);
    ResultSet records = query.executeQuery();
    try {
        return this.getCustomer(records);
    } finally {
        records.close();
    }
} finally {
    query.close();
}

また、ご使用のバージョンでは、records.close()が例外をスローした場合、クエリは閉じられません。

于 2012-05-25T23:26:36.413 に答える
1

DD のアノマリー ノートは機能というよりはバグだと思います。
また、リソースを解放する方法が少し不完全です。たとえば、

PreparedStatement pstmt = null;
Statement st = null; 

try {
    ...
} catch (final Exception e) {
    ...
} finally {
    try{
        if (pstmt != null) {
            pstmt.close();
        }
    } catch (final Exception e) {
        e.printStackTrace(System.err);
    } finally {
        try {
            if (st != null) {
                st.close();
            }
        } catch (final Exception e) {
            e.printStackTrace(System.err);
        }
    }
}

さらに、これは正しくありません。そのようなリソースを閉じる必要があるためです

PreparedStatement pstmt = null;
Throwable th = null;

try {
    ...
} catch (final Throwable e) {
    <something here>
    th = e;
    throw e;
} finally {
    if (th == null) {
        pstmt.close();
    } else {
        try {
            if (pstmt != null) {
                pstmt.close();
            }
        } catch (Throwable u) {
        }
    }
}
于 2013-09-25T06:56:43.440 に答える