2010-01-09 6 views
49

Я создаю приложение, которое извлекает изображения из Интернета. В случае невозможности получения изображения необходимо использовать другое локальное изображение.Java: как проверить, является ли объект нулевым?

При попытке выполнить следующие строки:

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath()); 
if (drawable.equals(null)) { 
    drawable = getRandomDrawable(); 
} 

линии, если (drawable.equals (нуль)) генерирует исключение, если рисуем является недействительным.

Кто-нибудь знает, как должно быть проверено значение drawable, чтобы исключить исключение, если оно является нулевым и получить локальное изображение (выполнить drawable = getRandomDrawable())?

+18

Используйте * если (рисуем == NULL) * Вызов любого метода на объекте NULL это исключение NullPointerException. – diciu

+3

Почему бы вам не написать обычный ответ вместо комментария, diciu? – deamon

+0

@JaredBurrows Не редактируйте код в вопросе таким образом, чтобы победить цель вопроса! – Gilles

ответ

22

Edited Java 8 Решение:

final Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath())) 
     .orElseGet(() -> getRandomDrawable()); 

Вы можете объявить drawablefinal в этом случае.

Как отметил Chasmo, Android не поддерживает Java 8 на данный момент. Таким образом, это решение возможно только в других контекстах.

+6

Вероятно, это не очень хорошая идея - вы возвращаетесь в Fortran 60, где оцениваются обе стороны условного выражения, затем используется только один. Это плохо, если неиспользуемая ветвь имеет какое-либо вычисление, которое истинно больше всего времени, поэтому оно не является обычно полезным методом. Я бы переместил условие в класс «Common» и разрешил вам предоставлять резервный URL-адрес и сохранять обязанности вместе. –

+1

Пример теперь полностью переписан на Java 8, поэтому мое решение больше не имеет ненужных оценок (как отметил @PeteKirkham в моем исходном решении). – deamon

+1

Android не поддерживает Java 8. Он поддерживает только до Java 7 (если у вас есть kitkat), и при этом он не имеет invokedynamic, а только новый синтаксический сахар. Кроме того, 'Optional.of' подразумевает, что значение не является нулевым, и поэтому' orElseGet' не нужно. В этом случае вы должны использовать 'Optional.ofNullable'. –

130
if (drawable == null) { 
    ... 
} 

В equals() метод проверяет значение равенства, что означает, что он сравнивает содержимое из двух объектов. Поскольку не является объектом, это приводит к сбою при попытке сравнить содержимое вашего объекта с содержимым null.

== В оператор проверяет ссылки равенства, а это значит, что он выглядит ли два объекта на самом деле тот же объект. Это не требует, чтобы объекты действительно существовали; два несуществующих объекта (null ссылок) также равны.

+45

Я хочу добавить очень ценный совет: если у вас есть строки или константы для сравнения, * always * помещайте их сначала в предложение equals. (если ("койот" .equals (myDogString))) гораздо лучше, чем (если (myDogString.equals ("Койот"))) , потому что во втором случае myDogString может быть пустыми и выбрасывает NPE время в первом случае не имеет значения, имеет ли myDogString значение null. –

+16

Известный как условие Йода: «если койот, собака ...» – Thomas

+1

Я также хотел бы добавить, что с Java 7 существует метод Objects.equals(), который позволит вам не беспокоиться о синтаксисе Yoda – maryokhin

3
drawable.equals(null) 

Вышеупомянутая строка вызывает метод «equals (...)» на подлежащем рисованию объекте.

Так что, когда рисуем не равно нулю, и это реальный объект, то все идет хорошо, как вызов на «равных (нуль)» метод возвращает «ложь»

Но когда «вытяжке» равно нулю, то это означает вызов метода «equals (...)» для нулевого объекта, означает вызов метода для объекта, который не существует, поэтому он выбрасывает «NullPointerException»

Чтобы проверить, существует ли объект, и он не является нулевым , используйте следующее:

if(drawable == null) { 
    ... 
    ... 
} 

В вышеуказанном состоянии мы являемся че Cking, что ссылочная переменная «вытяжке» равно нулю, либо содержит некоторое значение (ссылка на его объект), поэтому он не будет бросать исключение в случае Drawable является недействительным как проверка

null == null 

является действительным.

13

Я использую этот подход:

if (null == drawable) { 
    //do stuff 
} else { 
    //other things 
} 

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

С вопросами, почему вы не можете позвонить по телефону .equals() на объект, который может быть null; если ссылка на объект у вас есть (а именно «drawable») - Фактически null, он не указывает на объект в куче. Это означает, что в куче нет объекта, на который может наступить вызов equals().

Удачи!

+2

Я тоже предпочитаю, чтобы (== ) построить как способ защитить себя от случайного назначения. – Scott

0

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

+0

Где находится двойная проверка в 'if x == null'? – deamon

+0

После инструкции if среда выполнения снова проверит нулевой указатель, когда объект используется. Однако я не знаю, оптимизировано ли это компилятором. –

+4

Это противоречит общепринятой мудрости, используя исключения в качестве потока управления. – James

5

if (yourObject instanceof yourClassName) будет оценивать до false, если yourObject является null.

0

Использование google guava libs для обработки является-нуль-проверка (обновление Deamon в)

Drawable drawable = Optional.of(Common.getDrawableFromUrl(this, product.getMapPath())).or(getRandomDrawable()); 
+0

Лучше использовать Java 8 'Optional' сегодня. – deamon

7

DIY

private boolean isNull(Object obj) { 
    return obj == null; 
} 

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath()); 
if (isNull(drawable)) { 
    drawable = getRandomDrawable(); 
} 
Смежные вопросы