Вопрос

Я думал, что Java имеет оценку короткого замыкания, но эта строка по-прежнему выдает исключение с нулевым указателем:

if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {

В данном случае perfectAgent является null, поэтому я просто хочу , чтобы все выражение возвращалось false, но мое приложение по-прежнему выходит из строя в этой строке с NullPointerException.

ПРАВКА, общий ответ:

С тех пор как perfectAgent является null, ничего справа от && должно быть выполнено, так как невозможно, чтобы выражение было истинным.Более того, это невозможно выполнить perfectAgent.getAddress() с тех пор как perfectAgent не содержит допустимой ссылки (она равна нулю и все такое).Я пытаюсь использовать оценку короткого замыкания, чтобы не проверять наличие null в отдельном операторе, поскольку это делает логику более неаккуратной.

ПРАВКА 2 (или я идиот):Да, как и во многих вещах в жизни, ты находишь ответ сразу после того, как объявляешь всему миру, что ты идиот.В этом случае я отключил автоматическую сборку Eclipse, делая что-то еще, и не включил ее снова, поэтому я отлаживал файлы классов, которые не совпадали с моим исходным кодом.

Это было полезно?

Решение

Урок расширенной отладки №1:

Если вы столкнетесь с, казалось бы, невозможной ошибкой (напримертот, который противоречит вашим знаниям о Java), выполните следующие действия:

  • Обратитесь к авторитетному учебнику (или, что еще лучше, к соответствующему стандарту), чтобы убедиться, что ваше понимание не является ошибочным.(В данном случае ваше понимание было правильным, и любой мало-мальски приличный учебник подтвердил бы это через минуту.)

  • Проверьте все глупости, которые вы могли бы натворить и которые могли бы вызвать ошибку impossible.Такие вещи, как не сохранение файла, неполное выполнение сборки, запуск старой / устаревшей версии приложения, нахождение в неправильном каталоге и так далее.

Подводя итог, научитесь немного больше сомневаться в себе.

Другие советы

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

Так что да, ваша интуиция права - это не должно быть проблемой. Ищите в другом месте причину. Я сильно подозреваю, что perfectAgent не является фактически нулевым, и что вы сталкиваетесь с любой другой ситуацией в этом коде, которая может вызвать исключение.

Я предлагаю вам попытаться извлечь этот фрагмент кода в короткий, но полный пример - если вы сможете это сделать, я съем свою метафорическую шляпу; в противном случае вы, вероятно, найдете проблему при попытке извлечения.

Что заставляет вас думать, что perfectAgent действительно является нулевым? Попробуйте вставить этот код перед ним:

if (perfectAgent == null)
{
    System.out.println("Yup, it's null");
}

Еще одна очень, очень тонкая возможность заключается в том, что вы столкнулись с ошибкой JIT - но я в этом сильно сомневаюсь.

Java действительно имеет оценку короткого замыкания. Возможно, entry является null , и поэтому entry.getKey () вызывает NullPointerException . Другая возможность состоит в том, что getAddress () либо возвращает null , либо внутри где-то происходит NullPointerException (если это сложнее, чем простой возврат заявление).

РЕДАКТИРОВАТЬ. Я вижу ваше изменение, где вы заявляете следующее:

  

Более того, невозможно выполнить perfectAgent.getAddress () ...

Но что если perfectAgent.getAddress () успешно выполнится и вернет null ? Посмотрите, что я имею в виду ...

Вы гарантируете, что perfectAgent не является нулевым, поэтому один или несколько из perfectAgent.getAddress () или entry или entry. getKey () должен быть нулевым. Или getAddress () или getKey () попадают в NPE в своей реализации.

Чтобы отладить подобные вещи, сначала посмотрите трассировку стека, чтобы определить местоположение. Это скажет вам, происходит ли это в getAddress () или в getKey (), или во вставленном фрагменте кода, который их вызывает. Затем, если он находится в этом фрагменте, добавьте некоторый код перед проверкой if, который является нулевым. Вы можете использовать старый добрый System.err.println () или утверждения . (Если вы используете утверждения, обязательно включите их с флагом -enableassertions команды java.)

Обновление . Таким образом, моя интерпретация оказалась неверной ... проблема представила два противоречивых факта (на этой линии был NPE, но короткое замыкание должно было произойти), и я автоматически Предполагалось, что первый факт был правдой, а второй - ложью, хотя на самом деле это была совершенно другая проблема из-за отключения автоматической сборки в Eclipse. Duh! При отладке чего-то «невозможного» это помогает быть радикально скептическим.

Есть три ссылки, отличные от perfectAgent, которые могут быть нулевыми:

  • perfectAgent.getAddress()
  • запись
  • запись.getKey()

Разбейте инструкцию или запустите ее в отладчике.

Большая тайна. Я скопировал вашу строку кода и протестировал с perfectAgent == null , entry == null , entry.getKey () == null и комбинациями из них: нет NPE в моем тестовом стенде (Java 1.6).

Какая бы это ни была досадная ошибка, я сомневаюсь, что она как-то связана с оценкой короткого замыкания. Если эта строка вызывает NPE, то, насколько я могу сказать, perfectAgent не равен нулю. Удачи и - покажите нам ошибку, как только вы ее поймали:)

Попробуйте отформатировать код следующим образом:

if( 
  (perfectAgent != null) 
  && (
      perfectAgent.getAddress()
      .equals(
       entry.getKey()
      )
     ) 
  ) {

Это должно дать вам лучшую запись строки трассировки стека.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top