/ / Чому findbugs кидає нульовий показник покажчика в цей код? - java, findbugs

Чому пошукові помилки викидають нульовий покажчик у цьому коді? - java, findbugs

Я запускаю 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);
}