PMD: аномалия DD/DU

Я использую Eclipse с PMD Plug-in (4.0.0.v20130510-1000) и получаю много таких нарушений:

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

В этом 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? И что именно это правило пытается предотвратить (т.е. Почему это плохая практика)?

Ответы

Ответ 1

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. Возможно, флаггируется. Таким образом, он уходит при назначении freq внутри catch.

При назначении freq в catch, (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, используя двойное преобразование, которое не генерирует исключение. Ведение журнала означало бы уровень серьезности в предпочтении вышеуказанного стиля. Вход в простую функцию преобразования при ошибке может быть не очень хорошим: слишком много протоколирования, игнорирование ведения журнала (?), Трудно восстановить.

Ответ 2

Вы можете обойти эту проблему (и отдельные проблемы немного более четко), извлекая разбор в отдельный метод:

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;
  }
}

И если у вас разные значения по умолчанию, вы также можете добавить версию с двумя аргументами: public static double parseDouble(final String input, final double defaultValue).