Java: "xx" .equals (переменная) лучше, чем variable.equals ("xx"), TRUE? - PullRequest
17 голосов
/ 13 июля 2010

Я рассматриваю руководство по наилучшим методам и рекомендациям по кодированию Java, я думаю, это сомнительно

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

String variable;

"xx".equals(variable) // OK

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

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

Это правда?

Ответы [ 8 ]

25 голосов
/ 14 июля 2010

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

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

Но:

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

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

10 голосов
/ 13 июля 2010

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

variable.equals("xx");

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

"xx".equals(variable);

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

4 голосов
/ 13 июля 2010

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

Вам решать, стоит ли эта защита боли, которую многие считают неестественной идиомой.

3 голосов
/ 14 июля 2010

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

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

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

3 голосов
/ 13 июля 2010

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

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

1 голос
/ 14 июля 2010

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

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

Кодирование для slop противоположно «Fail fast fail fail hard».

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

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

0 голосов
/ 06 июля 2017

В качестве дополнительного примечания приведем шаблон проектирования, в котором эта рекомендация по коду может не иметь никакого значения, поскольку строка (т.е. 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")));
0 голосов
/ 13 июля 2010

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

...