string == null
сравнивает, если объект нулевой. string.equals("foo")
сравнивает значение внутри этого объекта. string == "foo"
не всегда работает, потому что вы пытаетесь увидеть, совпадают ли объекты, а не значения, которые они представляют.
Более длинный ответ:
Если вы попробуете это, оно не будет работать, как вы обнаружили:
String foo = null;
if (foo.equals(null)) {
// That fails every time.
}
Причина в том, что foo имеет значение null, поэтому он не знает, что такое .equals; там нет объекта для вызова .equals.
То, что вы, вероятно, хотели, было:
String foo = null;
if (foo == null) {
// That will work.
}
Типичный способ защитить себя от нуля при работе со строками:
String foo = null;
String bar = "Some string";
...
if (foo != null && foo.equals(bar)) {
// Do something here.
}
Таким образом, если foo был нулевым, он не оценивает вторую половину условного, и все в порядке.
Самый простой способ, если вы используете строковый литерал (вместо переменной), это:
String foo = null;
...
if ("some String".equals(foo)) {
// Do something here.
}
Если вы хотите обойти это, у Apache Commons есть класс - StringUtils -, который обеспечивает безопасные для нуля операции String.
if (StringUtils.equals(foo, bar)) {
// Do something here.
}
Еще один ответ был шуткой, и сказал, что вы должны сделать это:
boolean isNull = false;
try {
stringname.equalsIgnoreCase(null);
} catch (NullPointerException npe) {
isNull = true;
}
Пожалуйста, не делай этого. Вы должны выбрасывать исключения только для ошибок, которые являются исключительными; если вы ожидаете нулевое значение, вы должны проверить его заранее и не позволять ему генерировать исключение.
В моей голове есть две причины для этого. Во-первых, исключения являются медленными; проверка на ноль выполняется быстро, но когда JVM выдает исключение, это занимает много времени. Во-вторых, код намного легче читать и поддерживать, если вы просто проверяете нулевой указатель заранее.