2010-01-09 4 views
49

Je crée une application qui récupère des images du web. Dans le cas où l'image ne peut pas être récupérée, une autre image locale devrait être utilisée.Java: Comment vérifier si l'objet est nul?

Tout en essayant d'exécuter les lignes suivantes:

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

La ligne if (drawable.equals (null)) renvoie une exception si drawable est nulle.

Est-ce que quelqu'un sait comment la valeur de drawable devrait être vérifiée afin de ne pas lever une exception si elle est nulle et récupérer l'image locale (execute drawable = getRandomDrawable())?

+18

Utiliser * if (drawable == null) * appel d'une méthode sur un objet NULL est une exception NullPointerException. – diciu

+3

Pourquoi n'écrivez-vous pas une réponse habituelle au lieu d'un commentaire, diciu? – deamon

+0

@JaredBurrows Ne modifiez pas le code d'une question d'une manière qui va à l'encontre de l'objectif de la question! – Gilles

Répondre

22

Modifié Java 8 Solution:

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

Vous pouvez déclarer drawablefinal dans ce cas.

Comme l'a souligné Chasmo, Android ne supporte pas Java 8 pour le moment. Cette solution n'est donc possible que dans d'autres contextes.

+6

Probablement pas une bonne idée - vous revenez à Fortran 60 où les deux côtés du conditionnel sont évalués, alors un seul s'habitue. C'est mauvais si la branche inutilisée a un quelconque calcul, ce qui est vrai la plupart du temps, donc ce n'est pas une méthode généralement utile. Je déplacerais la condition à la classe 'Common', et vous permet de fournir une URL de secours, et de garder les responsabilités ensemble. –

+1

L'exemple est maintenant complètement réécrit en Java 8, donc ma solution ne souffre plus d'évaluations inutiles (comme l'a souligné @PeteKirkham dans ma solution originale). – deamon

+1

Android ne supporte pas Java 8. Il ne supporte que jusqu'à Java 7 (si vous avez kitkat) et encore il n'a pas invoqué dynamique, seul le nouveau sucre de la syntaxe. A côté de cela, 'Optional.of' implique que la valeur n'est pas nulle et donc' theElseGet' est inutile. Vous devriez utiliser 'Optional.ofNullable' dans ce cas. –

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

Les contrôles de procédé equals() pour valeur égalité, ce qui signifie qu'il compare les contenu de deux objets. Puisque null n'est pas un objet, cela se bloque lorsque vous essayez de comparer le contenu de votre objet au contenu de null.

Les == opérateur vérifie pour l'égalité référence, ce qui signifie qu'il semble que les deux objets sont en fait la même objet. Cela ne nécessite pas que les objets existent réellement; deux objets inexistants (null références) sont également égaux.

+45

Je veux ajouter un conseil très utile: Si vous avez des chaînes ou des constantes à comparer, * toujours * les mettre en premier dans la clause égale. (si ("coyote" equals (myDogString))) est beaucoup mieux que (si (myDogString.equals ("coyote"))) parce que dans le second cas myDogString peut être nul et un plaids en NPE Dans le premier cas, cela n'a pas d'importance si myDogString est nul. –

+16

Connu comme une condition Yoda: "si un coyote, le chien est ..." – Thomas

+1

Je voudrais aussi ajouter, que depuis Java 7 il y a une méthode Objects.equals(), qui ne vous soucie pas de la syntaxe Yoda – maryokhin

3
drawable.equals(null) 

La ligne ci-dessus appelle la méthode "equals (...)" sur l'objet dessinable.

Ainsi, lorsque drawable n'est pas nul et il est un objet réel, alors tout va bien que d'appeler les « égaux (null) » méthode retourne « false »

Mais quand « drawable » est nulle, alors cela signifie appeler la méthode "equals (...)" sur un objet nul, c'est-à-dire appeler une méthode sur un objet qui n'existe pas pour lancer "NullPointerException"

Pour vérifier si un objet existe et il n'est pas null , utilisez le suivant

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

Dans les conditions ci-dessus, nous sommes che cking que la variable de référence « drawable » est null ou contient une valeur (référence à son objet) il ne jetterai pas exception en cas drawable est nul comme la vérification

null == null 

est valide.

13

J'utilise cette approche:

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

De cette façon, je trouve améliore la lisibilité de la ligne - comme je l'ai lu rapidement un fichier source, je peux le voir est un chèque nul.

En ce qui concerne la raison pour laquelle vous ne pouvez pas appeler .equals() sur un objet qui peut être null; si la référence d'objet que vous avez (à savoir 'drawable') est en fait null, elle ne pointe pas vers un objet sur le tas. Cela signifie qu'il n'y a aucun objet sur le tas sur lequel l'appel à equals() peut réussir.

Bonne chance!

+2

Je préfère aussi la construction if ( == ) comme moyen de me protéger d'une affectation accidentelle. – Scott

0

Il est probablement légèrement plus efficace d'intercepter une exception NullPointerException. Les méthodes ci-dessus signifient que l'exécution vérifie deux fois les pointeurs NULL.

+0

Où est la double vérification de la solution 'if x == null'? – deamon

+0

Après l'instruction if, le moteur d'exécution vérifie à nouveau la présence d'un pointeur NULL lorsque l'objet est utilisé. Je ne sais pas si cela est optimisé par le compilateur, cependant. –

+4

Cela va à l'encontre des idées reçues, en utilisant des exceptions comme flux de contrôle. – James

5

if (yourObject instanceof yourClassName) va évaluer à false si yourObject est null.

0

Utilisez google guava libs pour gérer est nulle vérification (la mise à jour de deamon)

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

Mieux utiliser Java 8 'Optional' aujourd'hui. – deamon

7

Bricolage

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

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath()); 
if (isNull(drawable)) { 
    drawable = getRandomDrawable(); 
} 
Questions connexes