Подтвердить что ты не робот

Java: "xx".equals(variable) лучше, чем variable.equals( "xx" ), TRUE?

Я пересматриваю руководство по передовым методам и рекомендации по кодированию java. Я думаю, что это сомнительно.

Рекомендации для:

String variable;

"xx".equals(variable) // OK

variable.equals("xx") //Not recomended

Потому что предотвращает появление исключений NullPointerException, которые не контролируются

Это правда?

4b9b3361

Ответ 1

Это очень распространенный метод, который заставляет тест возвращать значение false, если переменная имеет значение null, а не бросает NullPointerException. Но я думаю, я буду другим и скажу, что я не буду рассматривать это как рекомендацию, которую вы всегда должны придерживаться.

  • Я определенно думаю, что это то, о чем должны знать все программисты Java, поскольку это распространенная идиома.
  • Это также полезный способ сделать код более кратким (вы можете обрабатывать нулевой и не нулевой случай одновременно).

Но:

  • Это делает ваш код труднее читать: "Если синий цвет неба..."
  • Если вы только что отметили, что ваш аргумент не равен null в предыдущей строке, это не нужно.
  • Если вы забыли проверить значение null и кто-то пришел с нулевым аргументом, которого вы не ожидали, то NullPointerException не обязательно является наихудшим возможным результатом. Притворяясь, что все в порядке, а перенос до тех пор, пока он не завершится позже, на самом деле не является лучшей альтернативой. Неудачное быстро.

Лично я не думаю, что использование этой техники должно быть обязательным во всех случаях. Я думаю, что это должно быть оставлено на рассмотрение программиста в каждом конкретном случае. Важно убедиться, что вы правильно обработали нулевой случай и как вы это делаете, это зависит от ситуации. Проверка правильности обработки нулевых значений может быть частью рекомендаций по тестированию/обзору кода.

Ответ 2

Это правда. Если variable null в вашем примере,

variable.equals("xx");

будет вызывать NPE, потому что вы не можете вызвать метод (equals) для нулевого объекта. Но

"xx".equals(variable);

просто вернет false без ошибок.

Ответ 3

Собственно, я считаю, что оригинальная рекомендация верна. Если вы используете variable.equals("xx"), тогда вы получите NullPointerException, если variable равно null. Помещение постоянной строки с левой стороны позволяет избежать этой возможности.

Это зависит от того, стоит ли этой защите боль от того, что многие считают неестественной идиомой.

Ответ 4

Это общий метод, используемый в Java (и С#). Первая форма исключает исключение нулевого указателя, потому что метод .equals() вызывается в константной строке "xx", которая никогда не является нулевой. Непустая строка по сравнению с нулевым значением false.

Если вы знаете, что variable никогда не будет null (и ваша программа некорректна каким-либо другим способом, если она когда-либо равна нулю), то использование variable.equals("xx") в порядке.

Ответ 5

Верно, что использование любого свойства объекта таким образом поможет вам избежать NPE.

Но почему у нас есть Исключения, чтобы справиться с такими вещами.

Возможно, если вы используете "xx".equals(variable), вы никогда не узнаете, имеет ли значение переменной значение null или просто не равно "xx". ИМО лучше всего знать, что вы получаете нулевое значение в своей переменной, поэтому вы можете перепрограммировать его, а не просто игнорировать его.

Ответ 6

Если вам нужно проверить null, я считаю это более читаемым, чем if (variable != null && variable.equals("xx")). Это более личное предпочтение.

Ответ 7

Вы правильно относитесь к порядку проверки - если переменная равна нулю, вызов .equals в строковой константе будет препятствовать NPE - но я не уверен, что считаю это хорошей идеей; Лично я называю это "slop".

Slop - это когда вы не обнаруживаете ненормальное состояние, но на самом деле создаете привычки, чтобы лично избежать его обнаружения. Прохождение вокруг нуля в виде строки в течение длительного периода времени в конечном итоге приведет к ошибкам, которые могут быть неясными и трудно найти.

Кодирование для slop - это противоположность "Fail fast fail hard".

Использование значения null как строки может иногда делать отличное "специальное" значение, но тот факт, что вы пытаетесь сравнить его с чем-то, указывает на то, что ваше понимание системы неполно (в лучшем случае) - чем скорее вы найдете этот факт, тем лучше.

С другой стороны, делая все переменные окончательными по умолчанию, используя Generics и минимизируя видимость всех объектов/методов, это привычки, которые уменьшают slop.

Ответ 8

В качестве дополнительной заметки здесь приведен шаблон проектирования, в котором эта рекомендация кода может не иметь никакого значения, поскольку строка String (т.е. Optional<String>) никогда не является нулевой из-за вызова .isPresent() из шаблона проектирования:

Optional<String> gender = Optional.of("MALE");
if (gender.isPresent()) {
    System.out.println("Value available.");
} else {
    System.out.println("Value not available.");
}
gender.ifPresent(g -> System.out.println("Consumer: equals: " + g.equals("whatever")));