Я запускаю Findbugs на нашому коді через Sonarqube, і я отримую помилку для нульового перенаправлення вказівника:
Існує галузь заяви, яка, якщо вона виконується, гарантує, що a нульове значення буде відменено.
Несправний код просто такий:
public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
return (x != null || y != null)
&& ((x != null && y == null) || (x == null && y != null) || x.compareTo(y) != 0);
}
Мене цікавить, як це можливо. Єдине місце, де можливий NPE, - це зателефонувати на x.compareTo (y), але якщо x = null, Java ніколи не аналізуватиме цю гілку, правда?
Це помилка чи я щось пропускаю про те, як Java аналізуватиме цю заяву?
UPDATE
Дякуємо за вклад. Я врешті запропонував їм змінити це на щось на кшталт:
if (x!=null && y != null)
return x.compare(y);
else
return x!=y;
що мені здається трохи зрозумілішим. Якщо ніхто не погоджується на зміну, я зроблю так, як було запропоновано, і просто проігнорую проблему, хоча я б і цього уникав.
Відповіді:
5 за відповідь № 1Логіка є занадто складною для FindBugs, вона помиляється тут. Ви маєте рацію, що захищали від перенаправлення null
у цьому коді.
Я "спрощую його, щоб FindBugs це розумів, і щоб будь-який наступний людський читач також міг легко зрозуміти, що він робить:
public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
if (x == null) {
return y != null;
}
if (y == null) {
return x != null;
}
return x.compareTo(y) != 0;
}
Побічна примітка: Зазвичай у вас є метод перевірки рівність, і використовувати !
якщо ви хочете перевірити нерівність.
У коментарі ви сказали:
На жаль, це застарілий код я не маю права змінювати (я б хотів, щоб міг!)
Тоді вам доведеться зауважити, що FindBugs не можуть це зрозуміти, і зробити його винятком у налаштуваннях FindBugs (описані у цьому питанні відповіді)
0 для відповіді № 2
Я би написав цей метод таким чином:
public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
if (x == null) throw new IllegalArgumentException("x cannot be null");
if (y == null) throw new IllegalArgumentException("y cannot be null");
return (x.compareTo(y) != 0);
}
Я думаю, що це читати набагато простіше.
Якщо ви не хочете, щоб попередні умови, висловлені у винятках, я також скажу, що це зрозуміліше:
public static boolean isBigDecimalDifferent(BigDecimal x, BigDecimal y) {
if (x == null) return (y != null);
if (y == null) return (x != null);
return (x.compareTo(y) != 0);
}