Проверяет ли Java все аргументы в операторе && (и), даже если один из них является ложным?

У меня такой код:

if(object != null && object.field != null){
    object.field = "foo";
}

Предположим, что объект имеет значение null.

Этот код приводит к ошибке nullPointerException или просто если оператор не будет выполнен?

Если это так, как сделать рефакторинг этого кода более элегантным (если это возможно, конечно)?

Ответы

Ответ 1

У Java есть оценка короткого замыкания, т.е. ваш код должен быть ОК

Ответ 2

&& делает короткое замыкание, а & не будет.

Но с такими простыми вопросами, как это, лучше всего просто попробовать (идеон может помочь, когда у вас нет доступа к машине).

& & - http://ideone.com/LvV6w & Амп; - http://ideone.com/X5PdU

Наконец, место для проверки наверняка будет JLS §15.23. Не самая легкая вещь для чтения, в соответствующем разделе говорится: & & оператор подобен и (§15.22.2), но оценивает его правый операнд, только если значение его левого операнда истинно.

Ответ 3

Лучший способ узнать - попробовать, особенно для одного вопроса. Было бы и быстрее.

Ответ заключается в том, что Java не выполнит тело "if".

Ответ 4

Это не вызовет никаких NullPointerException. Условие будет оцениваться слева направо, и в момент нахождения первого выражения false он не будет оценивать оставшееся выражение.

Ответ 5

Один способ узнать это! Попробуй это! Как? Ну, сделайте метод, который выдает что-то:

public static boolean test(int i)
{
    System.out.println(i);
    return false;
}

...

if (test(1) && test(2) && test(3))
{
    // not reached
}

Отпечатки:

1

Итак, ответ на ваш вопрос "нет".

Ответ 7

Java имеет оценку короткого замыкания, поэтому будет хорошо.

Код выглядит нормально для меня, но вам действительно нужно проверить object.field != null? Я думаю, что тест можно опустить, поскольку вы никогда не используете переменную, просто установите ее.

С другой стороны, большинство программистов не будут обращаться к полям напрямую (object.field), а скорее через getters/setters (object.setField(x);). Без каких-либо дополнительных условий я не могу сказать, подходит ли это в вашем случае.

Ответ 8

& & и || условия останавливаются в точке, где они могут решить, является ли условие истинным/ложным, в вашем случае условие остановится сразу после object != null, и я думаю, что ваш код в этом случае просто хорош

Ответ 9

Если вы хотите, чтобы все ваши булевы выражения оценивались независимо от значения истинности каждого из них, вы можете использовать and и | вместо && и ||. Однако убедитесь, что вы используете их только в булевых выражениях. В отличие от && и ||, и | также имеют значение для числовых типов, которые полностью отличаются от их значения для булевых. http://ibiblio.org/java/course/week2/46.html

Ответ 10

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

if(object != null) 
{
    if(object.field != null)
    {
        object.field = "foo";
    }
}

Это делается точно так же, как вы, по существу, говорите, если первая логическая проверка не работает, не делайте вторую; это также исключение nullPointerException, поскольку object.field не будет проверяться, если объект не является нулевым.

Использование короткого замыкания по логическим значениям может стать раздражающим позже, так как когда у вас есть несколько команд bool if, становится сложнее эффективно отлаживать ту часть, которая закорочена.