Eviter les instructions! = Null

J’utilise object != null beaucoup pour éviter une NullPointerException .

Y a-t-il une bonne alternative à cela?

Par exemple:

 if (someobject != null) { someobject.doCalc(); } 

Cela évite une NullPointerException , quand il est inconnu si l’object est null ou non.

Notez que la réponse acceptée peut être obsolète, voir https://stackoverflow.com/a/2386013/12943 pour une approche plus récente.

Cela me semble être un problème relativement courant auquel les développeurs de niveau intermédiaire à intermédiaire ont tendance à faire face à un moment donné: ils ne savent pas ou ne font pas confiance aux contrats auxquels ils participent et reviennent en arrière pour des valeurs nulles. De plus, lors de l’écriture de leur propre code, ils ont tendance à renvoyer des valeurs nulles pour indiquer quelque chose, ce qui oblige l’appelant à rechercher les valeurs NULL.

Pour le dire autrement, il existe deux cas où la vérification de nullité apparaît:

  1. Où null est une réponse valide en termes de contrat; et

  2. Où ce n’est pas une réponse valide.

(2) est facile. Utilisez des instructions d’assertion (assertions) ou autorisez l’échec (par exemple, NullPointerException ). Les assertions sont une fonctionnalité Java hautement sous-utilisée qui a été ajoutée au 1.4. La syntaxe est la suivante:

 assert  

ou

 assert  :  

est une expression booléenne et est un object dont la sortie de la méthode toSsortingng() sera incluse dans l’erreur.

Une instruction assert lève une Error ( AssertionError ) si la condition n’est pas vraie. Par défaut, Java ignore les assertions. Vous pouvez activer les assertions en transmettant l’option -ea à la machine -ea . Vous pouvez activer et désactiver les assertions pour des classes et des packages individuels. Cela signifie que vous pouvez valider le code avec les assertions lors du développement et des tests, et les désactiver dans un environnement de production, bien que mes tests n’aient pratiquement pas eu d’impact sur les performances des assertions.

Ne pas utiliser d’assertions dans ce cas est OK car le code échouera, ce qui se produira si vous utilisez des assertions. La seule différence est qu’avec les assertions, cela peut arriver plus tôt, de manière plus significative et éventuellement avec des informations supplémentaires, ce qui peut vous aider à comprendre pourquoi cela s’est produit si vous ne vous y attendiez pas.

(1) est un peu plus difficile. Si vous n’avez aucun contrôle sur le code que vous appelez, vous êtes bloqué. Si null est une réponse valide, vous devez le vérifier.

Si c’est du code que vous contrôlez (et c’est souvent le cas), alors c’est une autre histoire. Évitez d’utiliser des valeurs nulles comme réponse. Avec des méthodes qui renvoient des collections, c’est facile: retournez des collections vides (ou des tableaux) à la place des valeurs NULL à peu près tout le temps.

Avec les non-collections, cela pourrait être plus difficile. Considérez ceci comme un exemple: si vous avez ces interfaces:

 public interface Action { void doSomething(); } public interface Parser { Action findAction(Ssortingng userInput); } 

où Parser prend la saisie utilisateur brute et trouve quelque chose à faire, peut-être si vous implémentez une interface de ligne de commande pour quelque chose. Maintenant, vous pouvez faire le contrat qu’il retourne null s’il n’y a pas d’action appropriée. Cela mène à la vérification null dont vous parlez.

Une solution alternative consiste à ne jamais renvoyer null et à la place utiliser le modèle Objet nul :

 public class MyParser implements Parser { private static Action DO_NOTHING = new Action() { public void doSomething() { /* do nothing */ } }; public Action findAction(Ssortingng userInput) { // ... if ( /* we can't find any actions */ ) { return DO_NOTHING; } } } 

Comparer:

 Parser parser = ParserFactory.getParser(); if (parser == null) { // now what? // this would be an example of where null isn't (or shouldn't be) a valid response } Action action = parser.findAction(someInput); if (action == null) { // do nothing } else { action.doSomething(); } 

à

 ParserFactory.getParser().findAction(someInput).doSomething(); 

ce qui est un bien meilleur design car il conduit à un code plus concis.

Cela dit, peut-être est-il tout à fait approprié que la méthode findAction () lance une exception avec un message d’erreur significatif – particulièrement dans ce cas où vous vous fiez à une entrée utilisateur. Il serait préférable pour la méthode findAction de lancer une exception que pour la méthode appelante avec une simple NullPointerException sans explication.

 try { ParserFactory.getParser().findAction(someInput).doSomething(); } catch(ActionNotFoundException anfe) { userConsole.err(anfe.getMessage()); } 

Ou si vous pensez que le mécanisme try / catch est trop laid, plutôt que Do Nothing, votre action par défaut devrait fournir un retour à l’utilisateur.

 public Action findAction(final Ssortingng userInput) { /* Code to return requested Action if found */ return new Action() { public void doSomething() { userConsole.err("Action not found: " + userInput); } } } 

Si vous utilisez (ou prévoyez d’utiliser) un IDE Java comme JetBrains IntelliJ IDEA , Eclipse ou Netbeans ou un outil tel que findbugs, vous pouvez utiliser des annotations pour résoudre ce problème.

En gros, vous avez @Nullable et @NotNull .

Vous pouvez utiliser dans la méthode et les parameters, comme ceci:

 @NotNull public static Ssortingng helloWorld() { return "Hello World"; } 

ou

 @Nullable public static Ssortingng helloWorld() { return "Hello World"; } 

Le deuxième exemple ne comstackra pas (dans IntelliJ IDEA).

Lorsque vous utilisez la première fonction helloWorld() dans un autre morceau de code:

 public static void main(Ssortingng[] args) { Ssortingng result = helloWorld(); if(result != null) { System.out.println(result); } } 

Maintenant, le compilateur IntelliJ IDEA vous dira que la vérification est inutile, car la fonction helloWorld() ne renverra jamais null .

En utilisant le paramètre

 void someMethod(@NotNull someParameter) { } 

si vous écrivez quelque chose comme:

 someMethod(null); 

Cela ne comstackra pas.

Dernier exemple utilisant @Nullable

 @Nullable iWantToDestroyEverything() { return null; } 

Ce faisant

 iWantToDestroyEverything().something(); 

Et vous pouvez être sûr que cela n’arrivera pas. 🙂

C’est un bon moyen de laisser le compilateur vérifier quelque chose de plus que d’habitude et de renforcer vos contrats. Malheureusement, ce n’est pas supporté par tous les compilateurs.

Dans IntelliJ IDEA 10.5 et @Nullable , ils ont ajouté la prise en charge de toutes les autres @Nullable @NotNull .

Voir l’article de blog Annotations @ Nullable / @ NotNull plus flexibles et configurables .

Si les valeurs NULL ne sont pas autorisées

Si votre méthode est appelée en externe, commencez par quelque chose comme ceci:

 public void method(Object object) { if (object == null) { throw new IllegalArgumentException("..."); } 

Ensuite, dans le rest de cette méthode, vous saurez que cet object n’est pas nul.

S’il s’agit d’une méthode interne (ne faisant pas partie d’une API), documentez simplement qu’il ne peut pas être nul, et c’est tout.

Exemple:

 public Ssortingng getFirst3Chars(Ssortingng text) { return text.subSsortingng(0, 3); } 

Cependant, si votre méthode ne fait que transmettre la valeur et que la méthode suivante le transmet, cela peut poser problème. Dans ce cas, vous pouvez vérifier l’argument comme ci-dessus.

Si null est autorisé

Cela dépend vraiment. Si trouver que je fais souvent quelque chose comme ceci:

 if (object == null) { // something } else { // something else } 

Donc, je twig, et fais deux choses complètement différentes. Il n’y a pas d’extrait de code laid, car j’ai vraiment besoin de faire deux choses différentes en fonction des données. Par exemple, devrais-je travailler sur l’entrée, ou devrais-je calculer une bonne valeur par défaut?


Il est rare que j’utilise l’idiome ” if (object != null && ... “).

Il peut être plus facile de vous donner des exemples, si vous montrez des exemples où vous utilisez généralement l’idiome.

Wow, je déteste presque append une autre réponse lorsque nous avons 57 façons différentes de recommander le NullObject pattern , mais je pense que certaines personnes intéressées par cette question aimeraient savoir qu’il y a une proposition sur la table pour Java 7 à append “null -safe handling ” – une syntaxe rationalisée pour la logique null-égal-nul.

L’exemple donné par Alex Miller ressemble à ceci:

 public Ssortingng getPostcode(Person person) { return person?.getAddress()?.getPostcode(); } 

Le ?. signifie seulement dé-référencer l’identifiant gauche s’il n’est pas nul, sinon évaluez le rest de l’expression comme null . Certaines personnes, comme Dick Wall, membre de Java Posse, et les électeurs de Devoxx aiment vraiment cette proposition, mais il y a aussi une opposition, car elle encouragera davantage l’utilisation de null comme valeur sentinelle.


Mise à jour: Une proposition officielle pour un opérateur null-safe dans Java 7 a été soumise sous Project Coin. La syntaxe est un peu différente de l’exemple ci-dessus, mais c’est la même notion.


Mise à jour: la proposition d’opérateur null-safe n’a pas été intégrée à Project Coin. Donc, vous ne verrez pas cette syntaxe en Java 7.

Si les valeurs non définies ne sont pas autorisées:

Vous pouvez configurer votre IDE pour vous avertir d’un déréférencement potentiel nul. Par exemple, dans Eclipse, voir Preferences> Java> Comstackr> Errors / Warnings / Null analysis .

Si des valeurs non définies sont autorisées:

Si vous souhaitez définir une nouvelle API où les valeurs non définies ont un sens , utilisez le modèle d’option (qui peut être familier avec les langages fonctionnels). Il présente les avantages suivants:

  • L’API indique explicitement si une entrée ou une sortie existe ou non.
  • Le compilateur vous oblige à gérer le cas “non défini”.
  • Option est une monade , il n’est donc pas nécessaire de vérifier la nullité verbeuse, utilisez simplement map / foreach / getOrElse ou un combinateur similaire pour utiliser la valeur en toute sécurité (exemple) .

Java 8 a une classe Optional intégrée (recommandée); pour les versions antérieures, il existe des alternatives à la bibliothèque, par exemple l’ Optional ou la fonctionJava de Guava . Mais, comme pour de nombreux modèles de style fonctionnel, l’utilisation d’Option en Java (même 8) se traduit par une certaine complexité, que vous pouvez réduire en utilisant un langage JVM moins prolixe, par exemple Scala ou Xtend.

Si vous devez gérer une API qui pourrait renvoyer des valeurs nulles , vous ne pouvez pas faire grand chose en Java. Xtend et Groovy ont l’ opérateur Elvis ?: Et l’ opérateur de déréférencement null-safe ?. , mais notez que cela retourne null en cas de référence null, donc il ne fait que “différer” le traitement correct de null.

Seulement pour cette situation –

Ne pas vérifier si une variable est nulle avant d’appeler une méthode égale (un exemple de comparaison de chaîne ci-dessous):

 if ( foo.equals("bar") ) { // ... } 

entraînera une NullPointerException si foo n’existe pas.

Vous pouvez éviter cela si vous comparez vos Ssortingng comme ceci:

 if ( "bar".equals(foo) ) { // ... } 

Avec Java 8 vient la nouvelle classe java.util.Optional qui résout sans doute une partie du problème. On peut au moins dire que cela améliore la lisibilité du code et, dans le cas des API publiques, clarifie le contrat de l’API pour le développeur client.

Ils travaillent comme ça:

Un object facultatif pour un type donné ( Fruit ) est créé en tant que type de retour d’une méthode. Il peut être vide ou contenir un object Fruit :

 public static Optional find(Ssortingng name, List fruits) { for (Fruit fruit : fruits) { if (fruit.getName().equals(name)) { return Optional.of(fruit); } } return Optional.empty(); } 

Regardez maintenant ce code où nous recherchons une liste de Fruit ( fruits ) pour une instance de fruit donnée:

 Optional found = find("lemon", fruits); if (found.isPresent()) { Fruit fruit = found.get(); Ssortingng name = fruit.getName(); } 

Vous pouvez utiliser l’opérateur map() pour effectuer un calcul ou extraire une valeur d’un object facultatif. orElse() vous permet de fournir un repli pour les valeurs manquantes.

 Ssortingng nameOrNull = find("lemon", fruits) .map(f -> f.getName()) .orElse("empty-name"); 

Bien sûr, la vérification de la valeur null / vide est toujours nécessaire, mais au moins le développeur est conscient que la valeur peut être vide et le risque d’oubli de vérifier est limité.

Dans une API créée à partir de zéro à l’aide de la commande Optional chaque fois qu’une valeur de retour peut être vide et renvoyant un object brut uniquement lorsqu’elle ne peut pas être null (convention), le code client peut abandonner les vérifications nulles sur les valeurs de retour d’object simples …

Bien sûr, Optional pourrait également être utilisé comme argument de méthode, peut-être un meilleur moyen d’indiquer des arguments facultatifs que 5 ou 10 méthodes de surcharge dans certains cas.

Optional offre d’autres méthodes pratiques, telles que orElse qui permettent d’utiliser une valeur par défaut et ifPresent qui fonctionne avec des expressions lambda .

Je vous invite à lire cet article (ma source principale pour écrire cette réponse) dans lequel les problèmes de NullPointerException (et de pointeur général en général) ainsi que la solution (partielle) apscope par Optional sont bien expliqués: Objets facultatifs Java .

Selon le type d’objects que vous vérifiez, vous pouvez utiliser certaines des classes des commodes apache telles que: apache commons lang et apache commons collections

Exemple:

 Ssortingng foo; ... if( SsortingngUtils.isBlank( foo ) ) { ///do something } 

ou (en fonction de ce que vous devez vérifier):

 Ssortingng foo; ... if( SsortingngUtils.isEmpty( foo ) ) { ///do something } 

La classe SsortingngUtils est l’une des nombreuses; il y a pas mal de bonnes classes dans les commons qui manipulent de manière sécurisée.

Voici un exemple de la façon dont vous pouvez utiliser la validation null dans JAVA lorsque vous incluez une bibliothèque apache (commons-lang-2.4.jar)

 public DOCUMENT read(Ssortingng xml, ValidationEventHandler validationEventHandler) { Validate.notNull(validationEventHandler,"ValidationHandler not Injected"); return read(new SsortingngReader(xml), true, validationEventHandler); } 

Et si vous utilisez Spring, Spring a également la même fonctionnalité dans son package, voir la bibliothèque (spring-2.4.6.jar)

Exemple d’utilisation de cette classe statique à partir de Spring (org.springframework.util.Assert)

 Assert.notNull(validationEventHandler,"ValidationHandler not Injected"); 
  • Si vous considérez qu’un object ne doit pas être nul (ou est un bogue), utilisez un assert.
  • Si votre méthode n’accepte pas les parameters nuls, dites-le dans le javadoc et utilisez une assertion.

Vous devez vérifier l’object! = Null si vous voulez gérer le cas où l’object peut être nul …

Il y a une proposition d’append de nouvelles annotations dans Java7 pour vous aider avec les parameters null / notnull: http://tech.puredanger.com/java7/#jsr308

Je suis fan du code “échec rapide”. Demandez-vous – faites-vous quelque chose d’utile dans le cas où le paramètre est nul? Si vous n’avez pas de réponse claire à ce que votre code devrait faire dans ce cas … C’est-à-dire qu’il ne devrait jamais être nul, ignorez-le et autorisez une exception NullPointerException. Le code appelant donnera tout autant de sens à un NPE qu’à une exception IllegalArgumentException, mais il sera plus facile pour le développeur de déboguer et de comprendre ce qui ne va pas si un NPE est lancé plutôt que de tenter d’exécuter une autre éventualité imprévue. logique – qui aboutit finalement à l’échec de l’application de toute façon.

Parfois, vous avez des méthodes qui fonctionnent sur ses parameters qui définissent une opération symésortingque:

 af(b); <-> bf(a); 

Si vous savez que b ne peut jamais être nul, vous pouvez simplement l’échanger. C’est très utile pour les égaux: au lieu de foo.equals("bar"); mieux vaut "bar".equals(foo); .

Le cadre de collecte de Google offre un moyen efficace et élégant d’obtenir la vérification de nullité.

Il existe une méthode dans une classe de bibliothèque comme celle-ci:

 static  T checkNotNull(T e) { if (e == null) { throw new NullPointerException(); } return e; } 

Et l’utilisation est (avec l’ import static ):

 ... void foo(int a, Person p) { if (checkNotNull(p).getAge() > a) { ... } else { ... } } ... 

Ou dans votre exemple:

 checkNotNull(someobject).doCalc(); 

Plutôt que le modèle d’object nul – qui a ses utilisations – vous pouvez envisager des situations où l’object nul est un bogue.

Lorsque l’exception est levée, examinez la trace de la stack et traitez le bogue.

Java 7 a une nouvelle classe d’utilitaire java.util.Objects sur laquelle se trouve une méthode requireNonNull() . All this does is throw a NullPointerException if its argument is null, but it cleans up the code a bit. Exemple:

 Objects.requireNonNull(someObject); someObject.doCalc(); 

The method is most useful for checking just before an assignment in a constructor, where each use of it can save three lines of code:

 Parent(Child child) { if (child == null) { throw new NullPointerException("child"); } this.child = child; } 

devient

 Parent(Child child) { this.child = Objects.requireNonNull(child, "child"); } 

Null is not a ‘problem’. It is an integral part of a complete modeling tool set. Software aims to model the complexity of the world and null bears its burden. Null indicates ‘No data’ or ‘Unknown’ in Java and the like. So it is appropriate to use nulls for these purposes. I don’t prefer the ‘Null object’ pattern; I think it rise the ‘ who will guard the guardians ‘ problem.
If you ask me what is the name of my girlfriend I’ll tell you that I have no girlfriend. In the Java language I’ll return null. An alternative would be to throw meaningful exception to indicate some problem that can’t be (or don’t want to be) solved right there and delegate it somewhere higher in the stack to retry or report data access error to the user.

  1. For an ‘unknown question’ give ‘unknown answer’. (Be null-safe where this is correct from business point of view) Checking arguments for null once inside a method before usage relieves multiple callers from checking them before a call.

     public Photo getPhotoOfThePerson(Person person) { if (person == null) return null; // Grabbing some resources or intensive calculation // using person object anyhow. } 

    Previous leads to normal logic flow to get no photo of a non-existent girlfriend from my photo library.

     getPhotoOfThePerson(me.getGirlfriend()) 

    And it fits with new coming Java API (looking forward)

     getPhotoByName(me.getGirlfriend()?.getName()) 

    While it is rather ‘normal business flow’ not to find photo stored into the DB for some person, I used to use pairs like below for some other cases

     public static MyEnum parseMyEnum(Ssortingng value); // throws IllegalArgumentException public static MyEnum parseMyEnumOrNull(Ssortingng value); 

    And don’t loathe to type + + (generate javadoc in Eclipse) and write three additional words for you public API. This will be more than enough for all but those who don’t read documentation.

     /** * @return photo or null */ 

    ou

     /** * @return photo, never null */ 
  2. This is rather theoretical case and in most cases you should prefer java null safe API (in case it will be released in another 10 years), but NullPointerException is subclass of an Exception . Thus it is a form of Throwable that indicates conditions that a reasonable application might want to catch ( javadoc )! To use the first most advantage of exceptions and separate error-handling code from ‘regular’ code ( according to creators of Java ) it is appropriate, as for me, to catch NullPointerException .

     public Photo getGirlfriendPhoto() { try { return appContext.getPhotoDataSource().getPhotoByName(me.getGirlfriend().getName()); } catch (NullPointerException e) { return null; } } 

    Questions could arise:

    Q. What if getPhotoDataSource() returns null?
    A. It is up to business logic. If I fail to find a photo album I’ll show you no photos. What if appContext is not initialized? This method’s business logic puts up with this. If the same logic should be more ssortingct then throwing an exception it is part of the business logic and explicit check for null should be used (case 3). The new Java Null-safe API fits better here to specify selectively what implies and what does not imply to be initialized to be fail-fast in case of programmer errors.

    Q. Redundant code could be executed and unnecessary resources could be grabbed.
    A. It could take place if getPhotoByName() would try to open a database connection, create PreparedStatement and use the person name as an SQL parameter at last. The approach for an unknown question gives an unknown answer (case 1) works here. Before grabbing resources the method should check parameters and return ‘unknown’ result if needed.

    Q. This approach has a performance penalty due to the try closure opening.
    A. Software should be easy to understand and modify firstly. Only after this, one could think about performance, and only if needed! and where needed! ( source ), and many others).

    PS This approach will be as reasonable to use as the separate error-handling code from “regular” code principle is reasonable to use in some place. Consider the next example:

     public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) { try { Result1 result1 = performSomeCalculation(predicate); Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty()); Result3 result3 = performThirdCalculation(result2.getSomeProperty()); Result4 result4 = performLastCalculation(result3.getSomeProperty()); return result4.getSomeProperty(); } catch (NullPointerException e) { return null; } } public SomeValue calculateSomeValueUsingSophisticatedLogic(Predicate predicate) { SomeValue result = null; if (predicate != null) { Result1 result1 = performSomeCalculation(predicate); if (result1 != null && result1.getSomeProperty() != null) { Result2 result2 = performSomeOtherCalculation(result1.getSomeProperty()); if (result2 != null && result2.getSomeProperty() != null) { Result3 result3 = performThirdCalculation(result2.getSomeProperty()); if (result3 != null && result3.getSomeProperty() != null) { Result4 result4 = performLastCalculation(result3.getSomeProperty()); if (result4 != null) { result = result4.getSomeProperty(); } } } } } return result; } 

    PPS. For those fast to downvote (and not so fast to read documentation) I would like to say that I’ve never caught a null-pointer exception (NPE) in my life. But this possibility was intentionally designed by the Java creators because NPE is a subclass of Exception . We have a precedent in Java history when ThreadDeath is an Error not because it is actually an application error, but solely because it was not intended to be caught! How much NPE fits to be an Error than ThreadDeath ! But it is not.

  3. Check for ‘No data’ only if business logic implies it.

     public void updatePersonPhoneNumber(Long personId, Ssortingng phoneNumber) { if (personId == null) return; DataSource dataSource = appContext.getStuffDataSource(); Person person = dataSource.getPersonById(personId); if (person != null) { person.setPhoneNumber(phoneNumber); dataSource.updatePerson(person); } else { Person = new Person(personId); person.setPhoneNumber(phoneNumber); dataSource.insertPerson(person); } } 

    et

     public void updatePersonPhoneNumber(Long personId, Ssortingng phoneNumber) { if (personId == null) return; DataSource dataSource = appContext.getStuffDataSource(); Person person = dataSource.getPersonById(personId); if (person == null) throw new SomeReasonableUserException("What are you thinking about ???"); person.setPhoneNumber(phoneNumber); dataSource.updatePerson(person); } 

    If appContext or dataSource is not initialized unhandled runtime NullPointerException will kill current thread and will be processed by Thread.defaultUncaughtExceptionHandler (for you to define and use your favorite logger or other notification mechanizm). If not set, ThreadGroup#uncaughtException will print stacktrace to system err. One should monitor application error log and open Jira issue for each unhandled exception which in fact is application error. Programmer should fix bug somewhere in initialization stuff.

Ultimately, the only way to completely solve this problem is by using a different programming language:

  • In Objective-C, you can do the equivalent of invoking a method on nil , and absolutely nothing will happen. This makes most null checks unnecessary, but it can make errors much harder to diagnose.
  • In Nice , a Java-derived language, there are two versions of all types: a potentially-null version and a not-null version. You can only invoke methods on not-null types. Potentially-null types can be converted to not-null types through explicit checking for null. This makes it much easier to know where null checks are necessary and where they aren’t.

Common “problem” in Java indeed.

First, my thoughts on this:

I consider that it is bad to “eat” something when NULL was passed where NULL isn’t a valid value. If you’re not exiting the method with some sort of error then it means nothing went wrong in your method which is not true. Then you probably return null in this case, and in the receiving method you again check for null, and it never ends, and you end up with “if != null”, etc..

So, IMHO, null must be a critical error which prevents further execution (that is, where null is not a valid value).

The way I solve this problem is this:

First, I follow this convention:

  1. All public methods / API always check its arguments for null
  2. All private methods do not check for null since they are controlled methods (just let die with nullpointer exception in case it wasn’t handled above)
  3. The only other methods which do not check for null are utility methods. They are public, but if you call them for some reason, you know what parameters you pass. This is like trying to boil water in the kettle without providing water…

And finally, in the code, the first line of the public method goes like this:

 ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate(); 

Note that addParam() returns self, so that you can add more parameters to check.

Method validate() will throw checked ValidationException if any of the parameters is null (checked or unchecked is more a design/taste issue, but my ValidationException is checked).

 void validate() throws ValidationException; 

The message will contain the following text if, for example, “plans” is null:

Illegal argument value null is encountered for parameter [plans]

As you can see, the second value in the addParam() method (ssortingng) is needed for the user message, because you cannot easily detect passed-in variable name, even with reflection (not subject of this post anyway…).

And yes, we know that beyond this line we will no longer encounter a null value so we just safely invoke methods on those objects.

This way, the code is clean, easy maintainable and readable.

Asking that question points out that you may be interestd in error handling strategies. Your team’s architect should decide how to work errors. There are several ways to do this:

  1. allow the Exceptions to ripple through – catch them at the ‘main loop’ or in some other managing routine.

    • check for error conditions and handle them appropriately

Sure do have a look at Aspect Oriented Programming, too – they have neat ways to insert if( o == null ) handleNull() into your bytecode.

In addition to using assert you can use the following:

 if (someobject == null) { // Handle null here then move on. } 

This is slightly better than:

 if (someobject != null) { ..... ..... ..... } 

Just don’t ever use null. Don’t allow it.

In my classes, most fields and local variables have non-null default values, and I add contract statements (always-on asserts) everywhere in the code to make sure this is being enforced (since it’s more succinct, and more expressive than letting it come up as an NPE and then having to resolve the line number, etc.).

Once I adopted this practice, I noticed that the problems seemed to fix themselves. You’d catch things much earlier in the development process just by accident and realize you had a weak spot.. and more importantly.. it helps encapsulate different modules’ concerns, different modules can ‘trust’ each other, and no more littering the code with if = null else constructs!

This is defensive programming and results in much cleaner code in the long run. Always sanitize the data, eg here by enforcing rigid standards, and the problems go away.

 class C { private final MyType mustBeSet; public C(MyType mything) { mustBeSet=Contract.notNull(mything); } private Ssortingng name = ""; public void setName(Ssortingng s) { name = Contract.notNull(s); } } class Contract { public static  T notNull(T t) { if (t == null) { throw new ContractException("argument must be non-null"); return t; } } 

The contracts are like mini-unit tests which are always running, even in production, and when things fail, you know why, rather than a random NPE you have to somehow figure out.

Guava, a very useful core library by Google, has a nice and useful API to avoid nulls. I find UsingAndAvoidingNullExplained very helpful.

As explained in the wiki:

Optional is a way of replacing a nullable T reference with a non-null value. An Optional may either contain a non-null T reference (in which case we say the reference is “present”), or it may contain nothing (in which case we say the reference is “absent”). It is never said to “contain null.”

Usage:

 Optional possible = Optional.of(5); possible.isPresent(); // returns true possible.get(); // returns 5 

This is a very common problem for every Java developer. So there is official support in Java 8 to address these issues without cluttered code.

Java 8 has introduced java.util.Optional . It is a container that may or may not hold a non-null value. Java 8 has given a safer way to handle an object whose value may be null in some of the cases. It is inspired from the ideas of Haskell and Scala .

In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present. As a consequence, you can prevent unintended null pointer exceptions.

In above example we have a home service factory that returns a handle to multiple appliances available in the home. But these services may or may not be available/functional; it means it may result in a NullPointerException. Instead of adding a null if condition before using any service, let’s wrap it in to Optional.

WRAPPING TO OPTION

Let’s consider a method to get a reference of a service from a factory. Instead of returning the service reference, wrap it with Optional. It lets the API user know that the returned service may or may not available/functional, use defensively

 public Optional getRefrigertorControl() { Service s = new RefrigeratorService(); //... return Optional.ofNullable(s); } 

As you see Optional.ofNullable() provides an easy way to get the reference wrapped. There are another ways to get the reference of Optional, either Optional.empty() & Optional.of() . One for returning an empty object instead of retuning null and the other to wrap a non-nullable object, respectively.

SO HOW EXACTLY IT HELPS TO AVOID A NULL CHECK?

Once you have wrapped a reference object, Optional provides many useful methods to invoke methods on a wrapped reference without NPE.

 Optional ref = homeServices.getRefrigertorControl(); ref.ifPresent(HomeServices::switchItOn); 

Optional.ifPresent invokes the given Consumer with a reference if it is a non-null value. Otherwise, it does nothing.

 @FunctionalInterface public interface Consumer 

Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects. It is so clean and easy to understand. In the above code example, HomeService.switchOn(Service) gets invoked if the Optional holding reference is non-null.

We use the ternary operator very often for checking null condition and return an alternative value or default value. Optional provides another way to handle the same condition without checking null. Optional.orElse(defaultObj) returns defaultObj if the Optional has a null value. Let’s use this in our sample code:

 public static Optional get() { service = Optional.of(service.orElse(new HomeServices())); return service; } 

Now HomeServices.get() does same thing, but in a better way. It checks whether the service is already initialized of not. If it is then return the same or create a new New service. Optional.orElse(T) helps to return a default value.

Finally, here is our NPE as well as null check-free code:

 import java.util.Optional; public class HomeServices { private static final int NOW = 0; private static Optional service; public static Optional get() { service = Optional.of(service.orElse(new HomeServices())); return service; } public Optional getRefrigertorControl() { Service s = new RefrigeratorService(); //... return Optional.ofNullable(s); } public static void main(Ssortingng[] args) { /* Get Home Services handle */ Optional homeServices = HomeServices.get(); if(homeServices != null) { Optional refrigertorControl = homeServices.get().getRefrigertorControl(); refrigertorControl.ifPresent(HomeServices::switchItOn); } } public static void switchItOn(Service s){ //... } } 

The complete post is NPE as well as Null check-free code … Really? .

I like articles from Nat Pryce. Here are the links:

  • Avoiding Nulls with Polymorphic Dispatch
  • Avoiding Nulls with “Tell, Don’t Ask” Style

In the articles there is also a link to a Git repository for a Java Maybe Type which I find interesting, but I don’t think it alone could decrease the checking code bloat. After doing some research on the Internet, I think != null code bloat could be decreased mainly by careful design.

I’ve sortinged the NullObjectPattern but for me is not always the best way to go. There are sometimes when a “no action” is not appropiate.

NullPointerException is a Runtime exception that means it’s developers fault and with enough experience it tells you exactly where is the error.

Now to the answer:

Try to make all your atsortingbutes and its accessors as private as possible or avoid to expose them to the clients at all. You can have the argument values in the constructor of course, but by reducing the scope you don’t let the client class pass an invalid value. If you need to modify the values, you can always create a new object . You check the values in the constructor only once and in the rest of the methods you can be almost sure that the values are not null.

Of course, experience is the better way to understand and apply this suggestion.

Byte!

Probably the best alternative for Java 8 or newer is to use the Optional class.

 Optional ssortingngToUse = Optional.of("optional is there"); ssortingngToUse.ifPresent(System.out::println); 

This is especially handy for long chains of possible null values. Exemple:

 Optional i = Optional.ofNullable(wsObject.getFoo()) .map(f -> f.getBar()) .map(b -> b.getBaz()) .map(b -> b.getInt()); 

Example on how to throw exception on null:

 Optional optionalCarNull = Optional.ofNullable(someNull); optionalCarNull.orElseThrow(IllegalStateException::new); 

Java 7 introduced the Objects.requireNonNull method which can be handy when something should be checked for non-nullness. Exemple:

 Ssortingng lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase(); 

May I answer it more generally!

We usually face this issue when the methods get the parameters in the way we not expected (bad method call is programmer’s fault). For example: you expect to get an object, instead you get a null. You expect to get an Ssortingng with at least one character, instead you get an empty Ssortingng …

So there is no difference between:

 if(object == null){ //you called my method badly! 

}

ou

 if(str.length() == 0){ //you called my method badly again! } 

They both want to make sure that we received valid parameters, before we do any other functions.

As mentioned in some other answers, to avoid above problems you can follow the Design by contract pattern. Please see http://en.wikipedia.org/wiki/Design_by_contract .

To implement this pattern in java, you can use core java annotations like javax.annotation.NotNull or use more sophisticated libraries like Hibernate Validator .

Just a sample:

 getCustomerAccounts(@NotEmpty Ssortingng customerId,@Size(min = 1) Ssortingng accountType) 

Now you can safely develop the core function of your method without needing to check input parameters, they guard your methods from unexpected parameters.

You can go a step further and make sure that only valid pojos could be created in your application. (sample from hibernate validator site)

 public class Car { @NotNull private Ssortingng manufacturer; @NotNull @Size(min = 2, max = 14) private Ssortingng licensePlate; @Min(2) private int seatCount; // ... } 

I highly disregard answers that suggest using the null objects in every situation. This pattern may break the contract and bury problems deeper and deeper instead of solving them, not mentioning that used inappropriately will create another stack of boilerplate code that will require future maintenance.

In reality if something returned from a method can be null and the calling code has to make decision upon that, there should an earlier call that ensures the state.

Also keep in mind, that null object pattern will be memory hungry if used without care. For this – the instance of a NullObject should be shared between owners, and not be an unigue instance for each of these.

Also I would not recommend using this pattern where the type is meant to be a primitive type representation – like mathematical entities, that are not scalars: vectors, masortingces, complex numbers and POD(Plain Old Data) objects, which are meant to hold state in form of Java built-in types. In the latter case you would end up calling getter methods with arbitrary results. For example what should a NullPerson.getName() method return?

It’s worth considering such cases in order to avoid absurd results.

  1. Never initialise variables to null.
  2. If (1) is not possible, initialise all collections and arrays to empty collections/arrays.

Doing this in your own code and you can avoid != null checks.

Most of the time null checks seem to guard loops over collections or arrays, so just initialise them empty, you won’t need any null checks.

 // Bad ArrayList lemmings; Ssortingng[] names; void checkLemmings() { if (lemmings != null) for(lemming: lemmings) { // do something } } // Good ArrayList lemmings = new ArrayList(); Ssortingng[] names = {}; void checkLemmings() { for(lemming: lemmings) { // do something } } 

There is a tiny overhead in this, but it’s worth it for cleaner code and less NullPointerExceptions.

This is the most common error occurred for most of the developers.

We have number of ways to handle this.

Approach 1:

 org.apache.commons.lang.Validate //using apache framework 

notNull(Object object, Ssortingng message)

Approach 2:

 if(someObject!=null){ // simply checking against null } 

Approach 3:

 @isNull @Nullable // using annotation based validation 

Approach 4:

 // by writing static method and calling it across whereever we needed to check the validation static  T isNull(someObject e){ if(e == null){ throw new NullPointerException(); } return e; } 
 public static  T ifNull(T toCheck, T ifNull) { if (toCheck == null) { return ifNull; } return toCheck; }