Оценка короткого замыкания Java
Я думал, что у Java есть оценка короткого замыкания, но эта строка все еще бросает исключение с нулевым указателем:
if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {
В этом случае perfectAgent
есть null
, поэтому я просто хочу, чтобы все выражение возвращало false
, но мое приложение все еще терпит крах в этой строке с помощью исключения NullPointerException.
EDIT, общий ответ:
Так как perfectAgent
есть null
, ничего справа от &&
не должно выполняться, так как невозможно, чтобы выражение было истинным. Более того, невозможно выполнить perfectAgent.getAddress()
, поскольку perfectAgent
не содержит действительной ссылки (она является нулевой и все). Я пытаюсь использовать оценку короткого замыкания, чтобы не проверять значение null в отдельном выражении, поскольку это делает логику более неаккуратной.
ИЗМЕНИТЬ 2 (или, я идиот):
Да, как и многие вещи в жизни, вы выяснили ответ сразу после объявления миру, что вы идиот. В этом случае я отключил автозапуск Eclipse, когда делал что-то еще и не возвращал его обратно, поэтому я отлаживал файлы классов, которые не совпадали с моим источником.
Ответы
Ответ 1
Расширенный урок отладки # 1:
Если вы столкнулись с невозможной ошибкой (например, противоречащей вашим знаниям о Java), выполните следующие действия:
-
Проконсультируйтесь с авторитетным учебником (или, еще лучше, соответствующим стандартом), чтобы подтвердить, что ваше понимание не является недостатком. (В этом случае ваше понимание было правильным, и любой полупристойный учебник подтвердил бы это через минуту.)
-
Проверьте все глупые вещи, которые вы могли бы сделать, которые могут вызвать невозможную ошибку. Такие вещи, как не сохранение файла, не выполнение полной сборки, запуск старой/устаревшей версии приложения, находящийся в неправильном каталоге и т.д.
Вкратце, научиться немного сомневаться в себе.
Ответ 2
Если perfectAgent
является истинно нулевым, этот код не будет генерировать исключение (по крайней мере, предполагая, что не происходит странных потоков событий, изменяя его от ненулевого значения до нуля на полпути через выражение). Я был бы в шоке, если бы вы могли подготовить короткую, но полную программу, демонстрирующую, что это так.
Итак, ваша интуиция правильная - это не должно быть проблемой. Посмотрите в другом месте по этой причине. Я сильно подозреваю, что perfectAgent
не является фактически нулевым, и что вы работаете в любой другой ситуации в этом коде, которая может вызвать исключение.
Я предлагаю вам попробовать извлечь этот фрагмент кода в короткий, но полный пример - если вы можете это сделать, я буду есть мою метафорическую шляпу; если нет, вы, надеюсь, найдете проблему, пока пытаетесь извлечь из нее.
Что заставляет вас думать, что perfectAgent
действительно имеет значение null? Попробуйте вставить этот код перед ним:
if (perfectAgent == null)
{
System.out.println("Yup, it null");
}
Еще одна очень, очень тонкая возможность заключается в том, что вы столкнулись с ошибкой JIT, но я очень сомневаюсь.
Ответ 3
У Java есть оценка короткого замыкания. Возможно, entry
null
, и поэтому entry.getKey()
вызывает NullPointerException
. Другая возможность заключается в том, что getAddress()
возвращает null
или имеет NullPointerException
, происходящий где-то (если он более сложный, чем простой оператор return
).
EDIT: я вижу ваше редактирование, где вы утверждаете следующее:
Более того, невозможно выполнить perfectAgent.getAddress()
...
Но что, если perfectAgent.getAddress()
успешно выполняется и возвращает null
? Посмотрите, что я имею в виду...
Ответ 4
Вы гарантируете, что perfectAgent
не является нулевым, поэтому один или несколько из perfectAgent.getAddress()
или entry
или entry.getKey()
должны быть пустыми. Или getAddress() или getKey() попадают в NPE в их реализации.
Чтобы отладить такие вещи, сначала найдите трассировку стека, чтобы скопировать местоположение. Это скажет вам, происходит ли это в getAddress() или в getKey() или в фрагментированном фрагменте кода, который их вызывает. Затем, если он в этом фрагменте, добавьте некоторый код перед тегом if для проверки, который является нулевым. Вы можете использовать старые старые версии System.err.println() или утверждения. (Если вы используете утверждения, обязательно включите их с флагом -enableassertions команды java.)
Обновление:. Таким образом, моя интерпретация оказалась неправильной... проблема представила два противоречивых факта (на этой линии был NPE, и все же короткое замыкание должно было произойти), и я автоматически предположил, что первый факт был истинным, а второй ложным, когда на самом деле это была другая проблема полностью из-за отключения автоматической сборки в Eclipse. Duh! При отладке чего-то "невозможного" это помогает радикально скептицизировать.
Ответ 5
Большая мистерия. Я скопировал вашу строку кода и протестировал с помощью perfectAgent == null
, entry == null
, entry.getKey() == null
и комбинаций из них: нет NPE на моем тестовом поле (Java 1.6).
Какая бы ни была неприятная ошибка, я сомневаюсь, что она имеет какое-то отношение к оценке короткого замыкания. Если эта строка вызывает NPE, то, насколько я могу судить, perfectAgent не равен нулю. Удачи и - покажите нам ошибку, как только вы ее поймали:)
Ответ 6
Есть три ссылки, отличные от perfectAgent, которые могут иметь значение null:
- perfectAgent.getAddress()
- запись
- entry.getKey()
Разбить оператор или запустить его в отладчике.
Ответ 7
Попробуйте форматировать свой код следующим образом:
if(
(perfectAgent != null)
&& (
perfectAgent.getAddress()
.equals(
entry.getKey()
)
)
) {
Он должен дать вам лучшую строку строки трассировки стека.