Java порядок сравнения ИЛИ - PullRequest
4 голосов
/ 21 июня 2011

следующий фрагмент бросает NPE, когда аргумент равен нулю?

public void doSomething(String string) {
    if (string.trim().equals("") || string==null) {
    [...]
    }
}

Я нашел это в чужом коде (кто-то, кто должен быть более опытным, чем я). Поскольку я столкнулся с трудностями с этим кодом, я хочу спросить, следует ли инвертировать сравнение или компилятор Java достаточно умен, чтобы поменять местами операнды. У меня нет прямого контроля над этим кодом, и это не дает мне NPE из-за множества блоков catch.

Спасибо

Ответы [ 6 ]

16 голосов
/ 21 июня 2011

Да.Этот фрагмент кода выдаст NullPointerException, когда string равно null.Рекомендуется изменить его на следующее:

public void doSomething(String string) {
    if (string==null || string.trim().equals("")) {
        // ...
    }
}
4 голосов
/ 21 июня 2011

Будет выброшено NullPointerException, потому что, если string равно нулю, и вы попытаетесь обрезать null, оно выдаст исключение.Попробуйте поставить нулевую проверку, прежде чем пытаться trim().

3 голосов
/ 21 июня 2011

Да, это выглядит глупо для меня. Это почти наверняка должно быть наоборот. Логические операторы Java (как в C и C ++) имеют функцию «короткого замыкания», при которой сначала вычисляется левый операнд, а затем правый операнд только при необходимости.

[Примечание: не могли ли вы просто попытаться запустить это, чтобы выяснить, вызывает ли оно исключение?]

2 голосов
/ 21 июня 2011

попробуйте это с if(!"".equals(someString)), что позволяет избежать явной нулевой проверки

2 голосов
/ 21 июня 2011

Да, каждая разумная IDE будет жаловаться на этот код, потому что правая половина никогда не может быть оценена.

 if (string.trim().equals("") || string==null) {

если строка равна нулю, левая часть бросает NPE, поэтому правая часть никогдаоценивается

2 голосов
/ 21 июня 2011

бинарные операторы с одинаковым приоритетом всегда оцениваются слева направо, за исключением присваивания (почти на каждом языке, о котором я могу думать). Это важно в этом случае, потому что || является оператором сокращения.Если результат известен, т.е. первое выражение истинно, второе выражение не будет оцениваться.Таким образом, правильный способ использования || и && для проверки на нулевое значение выглядит следующим образом.

if(text == null || text.method())

или

if(text != null && text.method2())

Порядок такой, как мы читаем слеванаправо (и сверху вниз) на английском языке.cf На японском вы читаете сверху вниз, затем справа налево.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...