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

If (x!= y) vs if (x == y)

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

 if(singleRequest !=null){
   // do my work
 }else{
   // do my other work
 }

PMD говорит `Avoid if (x != y) ..; else ..;

И описание ошибки выглядит следующим образом:

In an "if" expression with an "else" clause, avoid negation in
the test.  For example, rephrase:
if (x != y) diff(); else same();
as:
if (x == y) same(); else diff();
Most "if (x != y)" cases without an "else" are often return

но я все еще не могу понять влияние моего кода. Если бы кто-нибудь мог привести меня к примеру, я был бы признателен.

4b9b3361

Ответ 1

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

Ответ 2

PMD - это инструмент. PMD работает на основе эвристики. Кто-то решил эту эвристику; что отрицательные условные выражения с инструкциями else не являются "хорошим стилем".

Однако в этом случае, как я уже говорил в своих комментариях, опубликованный код - это как I. (В частности, с x != null, но не исключительно для этой конструкции.)

Это потому, что я не смотрю на условное (за исключением того, что его можно упростить, например, удаление двойных негативов, как показано Джим Кином), но я смотрю на логику ветвей или "поток".

То есть, я положил первую положительную ветвь. В этом случае я утверждаю, что

if (x != null) {
  doValid         // positive branch
} else {
  doFallback
}

семантически эквивалентно

if (isValid(x)) { // it looks like a "positive conditional" now
  doValid         // still positive branch
} else {
  doFallback
}

и, таким образом, является положительной ветвью.

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

Другим фактором, который может повлиять на выбранный условный выбор, является "немедленная область действия", например:

if (x == null) {
  // return, break, or
  throw new Exception("oops!");
} else {
  // But in this case, the else is silly
  // and should be removed for clarity (IMOHO) which,
  // if done, avoids the PMD warning entirely
} 

Вот как I последовательно (несколько отдельных исключений) записывает мой код: if (x != null) { .. }. Используйте доступные инструменты; и заставить их работать на вас. См. Ответ Стивена о том, как PMD можно настроить на более подходящий "вкус" здесь.

Ответ 3

Это проблема читаемости. Рассмотрим

if ( x != y ) 
{
}
else  // "if x doesn't not equal y"
{
}

против.

if ( x == y )
{
}
else  // "if x doesn't equal y"
{
}

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

if ( x != null )...

Ответ 4

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

например.

if (!checkbox.disabled) {
    // checkbox is enabled
} 
else {
    // checkbox is disabled
}

Ответ 5

Кто читает ваш код? Вы делаете. Компилятор делает. Или, может быть, помощник лектора. Сотрудник, который не может различать == и! =? Надеюсь, что нет.

Я могу только думать, что негативы плохи в сложных выражениях. (Контекст: по крайней мере для меня. Я знаю, что я расстроен в отладке в голове while(!expr && !expr2 || expr3) { })

ch=getch(); if (ch!='a') - это шаблон, который легко распространяется на if (ch!='a' || ch!='b'), которая всегда истинна, при этом звучание семантически корректно.

С точки зрения производительности лучше всего отсортировать вероятности.

if (more_probable) {
      ....
      unconditional_jump_to_end_of_block;
} else {
   ...
}

Этот выбор должен привести к повышению производительности, поскольку в более вероятной ветке нет штрафа за неправильное предсказание.

if (p && p->next), оцененный с точки зрения производительности, дает плохие результаты.

Ответ 6

Вам нужно избегать "не равных" в условии if. Это связано с тем, что, когда кто-то еще смотрит на ваш код, существует реальная возможность, что человек может игнорировать!= И может ошибиться в логике вашей программы.

В вашем случае вам может потребоваться обмен логикой if с логикой else и изменением!= to ==

Ответ 7

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

Мое личное эмпирическое правило заключается в том, что вы ожидаете быть "нормальным" случаем - это то, что вы должны проверить в if. Рассмотрим:

 if (x != y) {
   // do work here...
 } else {
   throw new IllegalArgumentException();
 }

В этой ситуации я бы сказал, что важная работа выполняется в случае x != y, так что вы должны проверить. Это связано с тем, что мне нравится организовывать код, чтобы на первом месте была важная работа, а затем выполнялась обработка исключительных случаев.

Ответ 8

Это потому, что "хороший стиль" говорит, что если возможные тесты должны быть "положительными", значит:

if (singleRequest == null){
   // do my other work
} else {
   // do my work
}

Легче читать, потому что тест "положительный" (т.е. "равно" не "не равно" ), и в конечном итоге улучшенная читаемость приводит к меньшим ошибкам.

Edited

Это особенно относится к тесту, например:

if (!str.equals("foo")) {

вы можете легко пропустить ! спереди, но если вы сделаете тест положительным, он будет намного чище.

Единственный раз, когда у вас должен быть отрицательный тест, нет блока else - тогда отрицательный тест неизбежен, если у вас нет пустого блока true, который сам по себе считается проблемой стиля.

Ответ 9

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

if (something == null) {
    throw new IllegalArgumentException("something must not be null");
}

// continue here