web-dev-qa-db-ja.com

PMDからのデータフロー異常分析警告

私はPMD Plug-in (4.0.0.v20130510-1000)でEclipseを使用しており、それらの違反の多くを取得します。

Found 'DD'-anomaly for variable 'freq' (lines '187'-'189').
Found 'DU'-anomaly for variable 'freq' (lines '189'-'333').

this SOの回答では、これらの異常は読み取られない値の割り当てに関連していると述べていますが、この場合、たとえば違反が発生します。

// here I get a DD anomaly
double freq = 0;
try {
  // here I get a DU anomaly
  freq = Double.parseDouble(getFrequencyTextField().getText());
} catch (final NumberFormatException e) {
  Log.e(e.getMessage());
}
if (freq < 10E6) doSomething();

初期化を削除してfreq = 0;catchブロックの行で、DDアノマリーは消えますが、両方の割り当てでDUアノマリーが発生します。

ここで私の質問:どのように対処すればよいですか? PMDの推奨ソリューションは何ですか?そして、このルールは正確に何を防止しようとしていますか(つまり、なぜそれが悪い習慣なのですか?)

19
brimborium
double freq; // (1)
try {
  // here I get a DU anomaly
  freq = Double.parseDouble(getFrequencyTextField().getText());
} catch (final NumberFormatException e) {
  Log.e(e.getMessage());
  freq = 0; // (2)
}
if (freq < 10E6) doSomething();

最初の問題は、catchでparseDouble割り当てがfreqに行われないことです。例外では、freqはまだ0です。フラグが設定されている可能性があります。したがって、catch内のfreqに割り当てると、それはなくなります。

キャッチでfreqに割り当てる場合、(2)、最初の割り当て(1)は読み取られないため、宣言のみで十分です。

より良いスタイルに関して:

try {
  // here I get a DU anomaly
  double freq = Double.parseDouble(getFrequencyTextField().getText());

  if (freq < 10E6) doSomething();
  ...

} catch (final NumberFormatException e) {
  Log.e(e.getMessage());
}

または、@ JoachimSauerの回答に従って、例外をスローしない二重変換を使用します。ロギングは、上記のスタイルを優先して、深刻度のレベルを示します。エラー時に単純な変換関数内でログを記録することは、スタイルが良くない可能性があります。ログが多すぎる、ログが無視される(?)、修復が困難です。

20
Joop Eggen

解析を別のメソッドに抽出することで、この問題を回避できます(そして、懸念事項をもう少し明確に分離できます)。

_double freq = parseDouble(getFrequencyTextField().getText());

// later in the class (or in a utility class):

public static double parseDouble(final String input) {
  try {
    return Double.parseDouble(input);
  } catch (final NumberFormatException e) {
    Log.e(e.getMessage());
    return 0;
  }
}
_

また、デフォルト値が異なる場合は、引数が2つのバージョンpublic static double parseDouble(final String input, final double defaultValue)を追加することもできます。

3
Joachim Sauer