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)
.