Search code examples
javajava-8guavanullableimmutables-library

Why immutable null is discouraged?


I'm currently using Immutable library for generating JSON object from my web application.

Looking at this chapter, the first line says:

The use of nullable attributes is discouraged.

So my question is:

1) why? what's wrong with a null object?

2) what if I'm using a wrapper of thirdy object and I don't know if item is null or not, so using the classing builder code will fail:

MyImmutableWrapperObject
    .builder().
    .mobile(input.getMobile()) // don't know if null or not
    .build();

Is there any optimal solution?

EDIT:

@JsonProperty("mobile")
public abstract Optional<String> mobile();  

...

// composing builder
if (input.getMobile() != null)
        builder.mobile(input.getMobile());

The produced json is:

"mobile": {
    "present": false
},

How can I completely remove the empty fields?

I read this, however it uses gson.toJson which return a String object which is not my desiderable way.

POSTEDIT:

I just found that Optional doesn't show real value even if present, but it just display the true/false value, so I don't need it.


Solution

  • That's exactly the point IMO, you don't know if an object is null or not; so when later using it you might obviously get a NullPointerException. By using a library that prohibits that, you will not care if something is null or not null (because it will not be null), thus less code and less if-statements that pollute the code with potential null checks.

    Also having a null reference might mean different things in different contexts. For example I've seen code that needs three states for a Boolean : true, false and no yet set(as null). I find that wrong, but still occasionally see it.

    That's the reason why Optional was introduced in Guava and now is in the JDK. It forces the user to actively do something with an Optional. For example:

      Optional<Integer> i...
    
      if(i.isPresent()).... // you are forced to do this check
    

    Well obviously you could do:

     i.get()
    

    but that method is documented that it might break.

    the same is simply not true for an reference:

     Integer i  = null;
     if(i == null) // this is not an operation that is mandatory
    

    The bet article I've seen/read to date on this subject is Guava explanation