2013-06-25 2 views
21

Перед вызовом функции объекта мне нужно проверить, является ли объект нулевым, чтобы избежать выброса NullPointerException.Лучший способ проверить нулевые значения в Java?

Каков наилучший способ для этого? Я рассмотрел эти методы.
Какая из лучших программ для Java?

// Method 1 
if (foo != null) { 
    if (foo.bar()) { 
     etc... 
    } 
} 

// Method 2 
if (foo != null ? foo.bar() : false) { 
    etc... 
} 

// Method 3 
try { 
    if (foo.bar()) { 
     etc... 
    } 
} catch (NullPointerException e) { 
} 

// Method 4 -- Would this work, or would it still call foo.bar()? 
if (foo != null && foo.bar()) { 
    etc... 
} 
+7

Никогда не перехватывайте исключения исключений в виде указателей. Он попадает в категорию «Исключенные ошибки» http://blogs.msdn.com/б/ericlipp ert/archive/2008/09/10/vexing-exceptions.aspx –

+0

@NickFreeman Я так и думал, я просто добавил это для ясности, спасибо за объяснение, почему, хотя –

+1

В зависимости от вашего варианта использования также может иметь смысл запретить «null» 'значения для' foo' и бросать 'NullPointerException', если' null' foo передается вашему методу. – assylias

ответ

48

Способ 4 - т.

if(foo != null && foo.bar()) { 
    someStuff(); 
} 

будет использовать short-circuit evaluation, то есть она заканчивается, если первое условие logical AND является ложным.

+9

+1 для объяснения, почему это лучше всего – robjohncox

+1

Спасибо, я подумал, что это было бы лучше, но я не был уверен, почему он не назвал бы второе условие, или если бы он мог иногда - спасибо за объяснение, почему. –

11

Последний и лучший. т.е. ЛОГИЧЕСКОГО

if (foo != null && foo.bar()) { 
    etc... 
} 

Поскольку в логической &&

не нужно знать, что правая рука, результат должен быть ложным

Предпочитает читать: Java logical operator short-circuiting

5
  • Не поймать NullPointerException. Это плохая практика. Лучше убедиться, что значение не равно нулю.
  • Метод №4 будет работать для вас. Он не будет оценивать второе условие, потому что Java имеет короткое замыкание (т. Е. Последующие условия не будут оцениваться, если они не изменят конечный результат булевого выражения). В этом случае, если первое выражение логического И оценивается как false, последующие выражения не нужно оценивать.
+0

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

+0

@RichardTingle в большинстве случаев стоимость исключения является пренебрежимой (java использует их повсюду). Более того, исключение NullpointerException может происходить не только из foo, но и в любом месте между try {и} catch, чтобы вы могли скрыть ошибку, поймав ее. – josefx

+0

@josefx Стоимость выполнения (почти) чего-либо однажды незначительна, ее, очевидно, имеет значение только в том случае, если секция кода в ней - это горлышко бутылки; однако, если это тогда, вероятно, будет причиной. Я собрал некоторые данные в ответ на этот вопрос http://stackoverflow.com/questions/16320014/java-optimization-nitpick-is-it-faster-to-cast-something-and-let-it-throw-excep/16320082 # 16320082. Очевидно, что это также плохая идея по причинам, которые вы упомянули (кроме многих других). Возможно, я должен был сказать «одна из причин», а не «причина» –

2

Я бы сказал, что метод 4 является самой общей идиомой из кода, на который я смотрел. Но это всегда кажется мне вонючим. Предполагается, что foo == null совпадает с foo.bar() == false.

Это не всегда мне нравится.

2

Метод 4 - мой предпочтительный метод. Короткое замыкание оператора & & делает код наиболее читаемым. Метод 3, Catching NullPointerException, нахмурился большую часть времени, когда достаточно простой проверки нуля.

4

Метод 4 является лучшим и лучшим, поскольку он четко указывает, что произойдет и использует минимальный код.

Способ 3 на каждом уровне не соответствует действительности. Вы знаете, что элемент может быть нулевым, поэтому это не исключительная ситуация, за которую вы должны проверить.

Метод 2 просто усложняет его, чем нужно.

Метод 1 - это только метод 4 с дополнительной строкой кода.

0

, если у вас нет доступа к библиотеке Обще апача, следующий, вероятно, будет нормально работать

if(null != foo && foo.bar()) { 
//do something 
} 
+1

Второй снипп бросает NPE, когда foo имеет значение null. – Xaerxess

+0

Xaerxess, вы правы, я удалил фрагмент кода с возможным NPE –

+0

', если у вас нет доступа к библиотеке apache сообщества , в какой части библиотеки вы ссылались? – Maksim

0

Ваше последнее предложение является лучшим.

if (foo != null && foo.bar()) { 
    etc... 
} 

Потому что:

  1. Это легче читать.
  2. Это безопасно: foo.bar() никогда не будет выполняться, если foo == null.
  3. Это предотвращает неправильную практику, такую ​​как улавливание NullPointerExceptions (большую часть времени из-за ошибки в вашем коде)
  4. Он должен выполняться так быстро или даже быстрее, чем другие методы (хотя я думаю, что это должно быть практически невозможно обратите внимание на это).
1

Если вы контролируете API вызывается, рассмотреть вопрос об использовании Guava's Optional class

here Подробнее. Измените свой метод, чтобы вернуть Optional<Boolean> вместо Boolean.

В этом сообщает код вызова, что он должен учитывать возможность нулевой, позвонив по одному из удобных методов в Optional

2

В Java 7, вы можете использовать Objects.requireNonNull(). Добавить в корзину Objects класс от java.util.

public class FooClass { 
    //... 
    public void acceptFoo(Foo obj) { 
     //If obj is null, NPE is thrown 
     Objects.requireNonNull(obj).bar(); //or better requireNonNull(obj, "obj is null"); 
    } 
    //... 
} 
+0

Каким-то образом SO не позволяет мне добавить 'import java.util.Objects;' строку в код, поэтому поместите здесь комментарий. – KrishPrabakar

+0

В случае ** Java 8 ** вы можете попробовать использовать класс 'Optional'. – KrishPrabakar

+0

Будут вызывать NullPointer, если это Null – ScriptKiddy

1

Как утверждают другие, # 4 - лучший способ, когда не используется метод библиотеки. Однако вы всегда должны ставить нуль в левой части сравнения, чтобы убедиться, что вы случайно не назначили null для foo в случае опечатки. В этом случае компилятор поймает ошибку.

// You meant to do this 
if(foo != null){ 

// But you made a typo like this which will always evaluate to true 
if(foo = null) 

// Do the comparison in this way 
if(null != foo) 

// So if you make the mistake in this way the compiler will catch it 
if(null = foo){ 

// obviously the typo is less obvious when doing an equality comparison but it's a good habit either way 
if(foo == null){ 
if(foo = null){ 
2

В Java 8, лучший способ проверить это нуль:

Objects.isNull(obj) //returns true if the object is null 

Objects.nonNull(obj) //returns true if object is not-null 

if(Objects.nonNull(foo) && foo.something()) // Uses short-circuit as well. No Null-pointer Exceptions are thrown. 

Помимо этого ... Вы можете также пойти с Факультативным классом гуавы в

уменьшают типологические ошибки, как (obj=null), который всегда возвращает true, как обсуждалось в предыдущих ответах.

0

Мы можем использовать статический метод Object.requireNonNull класса Object. Реализация ниже

public void someMethod(SomeClass obj) { 
    Objects.requireNonNull(obj, "Validation error, obj cannot be null"); 
} 
0

Простой один код строки для проверки нуль:

namVar == null ? codTdoForNul() : codTdoForFul(); 
0

Вы также можете использовать StringUtils.isNoneEmpty("") для проверки является нулевым или пустым.

0

Если на все, что вы собираетесь проверить с двойной равным «==», а затем проверить нуль с объектом исх как

if(null == obj) 

вместо

if(obj == null) 

, потому что если вы ошиблись при вводе одного равны, если (OBJ = null), он вернет true (присвоение объекта возвращает успех (который является «истинным» в значении).

Смежные вопросы