Object == null или null == object?
Я слышал от кого-то, что null == object
лучше, чем object == null
check
например:
void m1(Object obj ) {
if(null == obj) // Is this better than object == null ? Why ?
return ;
// Else blah blah
}
Есть ли какие-то причины или это еще один миф?
Спасибо за помощь.
Ответы
Ответ 1
Это, вероятно, привычка, полученная из C, чтобы избежать такого рода опечатки (одиночный =
вместо double ==
):
if (object = null) {
Соглашение о переносе константы в левой части ==
на самом деле не очень полезно в Java, поскольку Java требует, чтобы выражение в if
оценивалось значением boolean
, поэтому, если константа не является boolean
, вы получите ошибку компиляции, как вы ставите аргументы. (и если это логическое значение, вы не должны использовать ==
в любом случае...)
Ответ 2
Как говорили другие, это была привычка, извлеченная из C, чтобы избежать опечаток - хотя даже в C я ожидал бы достойных компиляторов с достаточно высокими уровнями предупреждений, чтобы дать предупреждение. Как говорит Чандру, сравнение с нулем в Java таким образом могло бы вызвать проблемы, если бы вы использовали переменную типа Boolean
(которой вы не в образце кода). Я бы сказал, что это довольно редкая ситуация, и не одна, за которую стоит изменить способ написания кода везде. (Я бы не стал обращать вспять операнды даже в этом случае, если я думаю достаточно ясно, чтобы рассмотреть их реверсирование, я уверен, что могу считать знаки равенства.)
То, о чем не упоминалось, состоит в том, что многие люди (я, конечно же, включенные в него) находят форму if (variable == constant)
более читаемой - это более естественный способ выразить себя. Это причина не слепо копировать соглашение из C. Вы всегда должны задавать вопросы (как вы здесь делаете:), прежде чем считать, что то, что может быть полезно в одной среде, полезно в другом.
Ответ 3
Это не имеет большого значения в Java (1.5+), за исключением случаев, когда тип объекта Boolean
. В этом случае это может быть удобно.
if (object = null)
не приведет к сбою компиляции в Java 1.5+, если объект Boolean
, но будет запускать NullPointerException
во время выполнения.
Ответ 4
В Java нет веской причины.
Несколько других ответов утверждают, что это связано с тем, что вы можете случайно назначить это назначение вместо равенства. Но в Java вы должны иметь логическое значение в if, поэтому это:
if (o = null)
не будет компилироваться.
Единственный раз, когда это может иметь значение в Java, - если переменная имеет значение boolean:
int m1(boolean x)
{
if (x = true) // oops, assignment instead of equality
Ответ 5
Это также тесно связано с:
if ("foo".equals(bar)) {
что удобно, если вы не хотите иметь дело с NPE:
if (bar!=null && bar.equals("foo")) {
Ответ 6
Этот трюк должен предотвращать типы опечаток v = null
.
Но Java допускает только булевы выражения как условия if()
, так что трюк не имеет большого смысла, компилятор все равно найдет эти опечатки.
Это все еще ценный трюк для кода C/С++.
Ответ 7
По той же причине вы делаете это в C; присваивание - это выражение, поэтому вы помещаете литерал слева, чтобы не перезаписывать его, если вы случайно используете =
вместо ==
.
Ответ 8
Это для людей, которые предпочитают иметь постоянную с левой стороны.
В большинстве случаев наличие константы с левой стороны предотвратит выброс NullPointerException (или наличие еще одного nullcheck). Например, метод String равен также проверяет нуль. Имея постоянную слева, вы не сможете писать дополнительную проверку. Который, по-другому также выполняется позже. Наличие нулевого значения слева просто согласовано.
как:
String b = null;
"constant".equals(b); // result to false
b.equals("constant"); // NullPointerException
b != null && b.equals("constant"); // result to false
Ответ 9
Сравните со следующим кодом:
String pingResult = "asd";
long s = System.nanoTime ( );
if ( null != pingResult )
{
System.out.println ( "null != pingResult" );
}
long e = System.nanoTime ( );
System.out.println ( e - s );
long s1 = System.nanoTime ( );
if ( pingResult != null )
{
System.out.println ( "pingResult != null" );
}
long e1 = System.nanoTime ( );
System.out.println ( e1 - s1 );
Выход (после нескольких исполнений):
null != pingResult
325737
pingResult != null
47027
Поэтому pingResult != null
является победителем.
Ответ 10
Из-за его коммутативного свойства единственное различие между object == null
и null == object
(версия Yoda) имеет когнитивный характер: как читается код и усваивается читателем. Хотя я не знаю окончательного ответа, но я знаю, что лично я предпочитаю сравнивать объект, который я проверяю, с чем-то другим, а не сравнивать что-то еще с объектом, который я проверяю, если это имеет смысл. Начните с темы, а затем сравните ее со значением.
В некоторых других языках этот стиль сравнения более полезен.
Хотя, чтобы защитить себя от пропущенного знака "=" в целом, я думаю, что написание null == object
является ошибочным действием защитного программирования. Лучший способ обойти этот конкретный код - гарантировать поведение с помощью теста junit. Помните, что возможная ошибка пропуска "=" не зависит от входных аргументов метода - вы не зависите от правильного использования этого API другими людьми - поэтому тест junit идеально подходит для защиты от этого. В любом случае вы захотите написать тесты junit для проверки поведения; пропущенное "=" естественно попадает в сферу действия.
Ответ 11
Вышеуказанный вывод неверен. Просто запустите оба блока кода отдельно, и вы получите фактический результат. Оба будут в одно и то же время.
Также выполните приведенный ниже код:
String pingResult = "asd";
long s = System.nanoTime ( );
if ( null != pingResult )
{
//System.out.println ( "null != pingResult" );
}
long e = System.nanoTime ( );
System.out.println ( e - s );
long s1 = System.nanoTime ( );
if ( pingResult != null )
{
//System.out.println ( "pingResult != null" );
}
long e1 = System.nanoTime ( );
System.out.println ( e1 - s1 );
Ответ 12
Это условие написания Йоды по-разному
В Яве
String myString = null;
if (myString.equals("foobar")) { /* ... */ } //Will give u null pointer
йода состояние
String myString = null;
if ("foobar".equals(myString)) { /* ... */ } // will be false