aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Why null is a terrible practice in OOP and Java in particular? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Why null is a terrible practice in OOP and Java in particular?" Watch "Why null is a terrible practice in OOP and Java in particular?" New topic
Forums: Blog around the Campfire OO, Patterns, UML and Refactoring
Author

Why null is a terrible practice in OOP and Java in particular?

Yegor Bugayenko
Ranch Hand

Joined: Feb 11, 2011
Posts: 66
Check my recent blog post that explains why NULL is a bad practice in OOP (and in Java): http://www.yegor256.com/2014/05/13/why-null-is-bad.html

Ready to answer your questions and comments


follow me at yegor256.com
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  16

While I agree that the usage of null should be avoided, I think passing and returning null values is better than the use of Null Objects. The last reek of hiding programming or logic errors. When you get a NullPointerException somewhere, your program is obviously broken. With Null Objects, you pretend that everything is okay, and just go on. This is bad.

I'll just stick with doing parameter checking and throwing exceptions. It would have been nicer if Java didn't allow assigning null to reference types at all, except when you use some special syntax to allow it. I recently learned that C# doesn't allow you to assign null to enum variables, except when you use a bit of syntax sugar to make the type Nullable:
You may assign a Color to a Color?, but you have to explicitly check color2.HasValue to see if you can assign color2's value to a Color.
Claude Moore
Ranch Hand

Joined: Jun 24, 2005
Posts: 453
    
    1

Hi, i found your post on your blog interesting, thanks for sharing it! Having an (old, to be honest) backround in c++ and C, anyway, i have to admit that it sounds strange to read that null usage is a bad practice.. I used to use null values to identify a "not really existing object" or a not assigned variable. In java 8, an Optional class has been added to support NullObject pattern, but i'm not fully persuaded that it's a great enhancement.. what does it change between testing if myobj == null instead of testing a method like isNull() ? I'd prefer to throw an exception, to be honest..
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1018
    
  15
I had my first introduction to the null object pattern a few days back while studying the command pattern from the book 'head first design patterns'. I've been in awe of it
ever since. II think it works wonders in select cases, especially for initialising an unimplemented type. Good or not, I've used it once already and I like that piece of code. I like the new java.util.Optional class but at work we are still on Java 6. So the null object comes quite handy in some cases.
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1018
    
  15
I think I should also link a very beautiful 'Winston's another approach' to nulls for instances ( english ) in which what is not known can take a default value.

Of course you've got to evaluate other things that go with it and see if it fits your requirement, but I think it's also one of the things that we can consider.

Edit : One of the reasons I don't like nulls is that I think a null should be a run time error condition. You don't program your program to throw a null pointer exception. For Illegal arguments, we have parameter checking. But I wouldn't go so far as to say that throwing an NPE should never be done. If you have code that can throw an NPE, throwing it eagerly is better. Actually TBH I have mixed opinion about nulls. I think I don't like nulls and NPEs. So perhaps I'm a little biased.
Amar Saikia
Greenhorn

Joined: Feb 04, 2014
Posts: 29
    
    1
Recently, I also have found in 'Clean Code' that returning Nulls from a method or passing Nulls to a method is a bad practice, and I tend to buy author's argument. Checking Nulls really makes code ugly and now I try to avoid it. On the other hand if are returning Null from a method, probably we are not practicing coding standard correctly. for Ex: we have a method like




From the name of the method, we can expect that getEmployee() method will return Employee object. Atleast this is the 'intent' of the programmer. Returning Null will violate the intent and hence IMHO, its better to pass a Null object or Exception.
Dieter Quickfend
Bartender

Joined: Aug 06, 2010
Posts: 543
    
    4

Claude Moore wrote:Hi, i found your post on your blog interesting, thanks for sharing it! Having an (old, to be honest) backround in c++ and C, anyway, i have to admit that it sounds strange to read that null usage is a bad practice.. I used to use null values to identify a "not really existing object" or a not assigned variable. In java 8, an Optional class has been added to support NullObject pattern, but i'm not fully persuaded that it's a great enhancement.. what does it change between testing if myobj == null instead of testing a method like isNull() ? I'd prefer to throw an exception, to be honest..


One of the biggest problem in Java is try{}catch(){} blocks, because they make the code less readable. They're doing everything they can to still have the same benefit of Exceptions, but minimize the amount of clutter and complexity induced by things such as I/O. The same could be said for null references. While value types should be null sometimes, objects that contain references to other objects should either be preinitialized or return an Immutable implementation of of the return type, to avoid having to check every method call for null.

This way you can string method calls, which is currently a safety hazard in java. Either you check all objects in your method string for null references and thus forego stringing method calls, or you catch a runtime exception, which is just bad design. Checking null clutters your code, why check null for every call when you can just check null on the eventual value returned? If you eventually return void, nothing is done or, if you need it, an exception is thrown. This makes your code far more fluent and concise. While having no substantial downsides.


Oracle Certified Professional: Java SE 6 Programmer && Oracle Certified Expert: (JEE 6 Web Component Developer && JEE 6 EJB Developer)
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3647
    
  16

Then these classes simply shouldn't return null. A lot, if not most classes, can make this guarantee by doing parameter checking themselves, which really does not clutter code all that much.

As a matter of fact, often I don't even need to perform null checks in my methods, because I make sure to dereference the parameters before performing any other actions. You also often don't need to do any null checks on return values of methods, because classes guarantee they don't return null, and so should yours.

A word on method chaining and fluid interface. Don't overuse it. While I love method chaining for builder objects, business objects probably should just return void on actions. And chaining a whole bunch of getters together is often unnecessary, because you need to assign them to variables anyway. So while I like the following:
This is probably unnecessary:
While it's true that Washington may not have a Pennsylvania Avenue, and this example would be helped with Null Objects (you'd need one each for District, City and Street though), it's probably a very rare scenario to chain many getters like this. The problem doesn't arise for the QueryBuilder, because it guarantees that none of its return values will ever be null. It just returns a query object with which you can at a later moment (when querying the database) determine whether there is any associated data.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4392
    
    8

I tend to agree with Stephan's position. I'm not a great fan of Null objects, because a lot of the time you'd need to check if it's a Null object anyway, in just the same way that you check for null.

Throwing exceptions instead of returning null is fine when you've broken a pre-condition: so the calling code should have been in a position to know that there is nothing to return. But it's not appropriate when that is unknown - otherwise you're using an exception to control flow.

What I _do_ like is the approach taken by a number of functional languages (e.g. Scala - though that doesn't enforce it because it has to be compatible with Java), which is to not use null but to have an optional type. Then it's clear from the function signature whether you can expect it to always return a value or whether you have to cope with the possibility that there isn't one. And in some contexts the compiler can even force you to cope with the missing case.

The C# example of using nullable types is similar, but you can only use them with value types, not reference types. Which means you actually have two separate approaches to deal with. They're useful, but can lead to confusion.
Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1018
    
  15
I think the null design pattern should not be used if you're going to need checks of the following nature at some point in time.



For example, a Thread does not have to have a public void run() method that does something worthwhile.

You have a queue that holds some Commands/Runnables for example. Since Runnable/Command is a reference type, we could have the queue have a few nulls. The job of the queue is to run each of these Runnables/Comands and it cares nothing about whether the command is a sensible command or a bogus command. A No Command really fits this kind of a use case.

But if the queue was supposed to run only valid commands, we can't use the null object pattern here. Would that be right?

I think the null object pattern should not be used as a replacement for null checks. I don't know if it was ever meant to replace the null checks.

The bigger ( but a simpler ) question I have/ or that confuses me is - Suppose you have a constructor that takes a reference type. So now the caller can pass a null argument. So in such cases, should the constructor really have the following lines of code--



I mean isn't null just another illegal argument for such cases?

Ok, let's come to static methods that take reference type as arguments.

I was going to say that we shouldn't probably let the methods throws NPE for such cases but I realize that yes, it might be better to eagerly throw an NPE in such cases if these method arguments should not be null. Would that be right?

But I can't think of an example of a method that should return null.

Throwing exceptions instead of returning null is fine when you've broken a pre-condition: so the calling code should have been in a position to know that there is nothing to return. But it's not appropriate when that is unknown - otherwise you're using an exception to control flow.


Ok, let us consider this. The parameters to a method are ok, i.e they do not violate a pre condition. Let's consider that we have an Employee class. If the employee id starts with 9, the employee is eligible to have a badge. So what it returns is EligibilityForBadge. Actually there are only two valid eligibility types, eligible and not eligible. So we pass to this method an Employee whose employee id is not known. Sure, no pre condition is violated. Now the eligibility is also not known. So the eligibility is actually not known, i.e null.

Wouldn't we create an enum for this case - with a YES, NO, UNKNOWN. Isn't unknown in some way similar to the Null object pattern? Why in this case we don't think of returning a null.

Edit : Ok. I get it. If Eligibility wasn't an enum type, returning a null makes perfect sense in this case. Obviously null here is a valid thing that should be returned. And the caller should be extra careful to not throw an NPE after invoking this method. The caller would have to check if what is returned is null or not. So the null object pattern doesn't really lend any elegance here. Just with enums, we can easily test UNKNOWN like how we would test for nullls and for enum the UNKNOWN is sort of self documenting. So it might be better than null for that reason.

Sorry, this also became some sort of a personal dialogue. But I didn't have any such intentions.

Claude Moore
Ranch Hand

Joined: Jun 24, 2005
Posts: 453
    
    1

But if the queue was supposed to run only valid commands, we can't use the null object pattern here. Would that be right?

Why not ? In this case we may insert in the queue null Commands as well as Commands that aren't null, but that are provided with
an method. I see no (practical) difference.

it might be better to eagerly throw an NPE in such cases if these method arguments should not be null. Would that be right?


Or throw a custom ObjectCantBeInstantiated exception if you want more hints about what went wrong.
Anyway I'd like to understand which may be the substantial difference between



and



Moreover, if I try to "cheat" and use a Connection which is null, I'll run very soon in a NPE. With a not valid, but not null, Connection,i may create the very same way PreparedStatements logically null which, in turn, return not null but logically null resultsets..



Chan Ag
Bartender

Joined: Sep 06, 2012
Posts: 1018
    
  15
Claude Moore wrote:
But if the queue was supposed to run only valid commands, we can't use the null object pattern here. Would that be right?

Why not ? In this case we may insert in the queue null Commands as well as Commands that aren't null, but that are provided with
an method. I see no (practical) difference.


Actually I meant to say

"But if the queue was supposed to runhave only valid commands, we can'tshouldn't use the null object pattern here. Would that be right?"

for the same reason as mentioned by you, cause would be the same as checking for nulls.

So like you said, we'd get no practical gain, if the queue processor was supposed to process the commands intelligently.
Claude Moore
Ranch Hand

Joined: Jun 24, 2005
Posts: 453
    
    1

Moreover, I wonder if the choice between using null or replacing null with another concept may be lead by any mathematical or logical rule. I mean, let us suppose we have a method returning a list of object. Instead of returning null, which is nothing, i think that is more correct to return an empty list, which is not null and stands for "empty set" which is a well known math concept.. an exception thrown in a constructor may be similar to a "domain error" like when you try to calculate a function in a point in which it isn't defined... and so on.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18570
    
    8

On the other hand, I participated in a long thread a few months ago with a Ranch member who was adamantly against the idea of using empty arrays or empty lists to signify that there was no data to return. His point of view (which I oversimplify) was that arrays and lists were intended to contain data, so the concept of an array or list which didn't contain any data didn't make sense.

In other words there are a lot of people who have trouble with the concept of "nothing" and wouldn't appreciate the way in which a null object abstracts Java's "null" concept at all.
Claude Moore
Ranch Hand

Joined: Jun 24, 2005
Posts: 453
    
    1

Paul Clapham wrote:On the other hand, I participated in a long thread a few months ago with a Ranch member who was adamantly against the idea of using empty arrays or empty lists to signify that there was no data to return. His point of view (which I oversimplify) was that arrays and lists were intended to contain data, so the concept of an array or list which didn't contain any data didn't make sense.


That's not surprising....after all each of us has got his own ideas. Patterns - like NullObject - are "simply" good (and proven to work) ways to solve programming problems.
If you won't follow them, you won't burn in the hell. Generations of software programmers have dealed with NULLs values, at the very end, and we can presume
that their softwares aren't crashing continuosly with uncatched NPE :-o
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 1007
    
    3
Paul Clapham wrote:On the other hand, I participated in a long thread a few months ago with a Ranch member who was adamantly against the idea of using empty arrays or empty lists to signify that there was no data to return. His point of view (which I oversimplify) was that arrays and lists were intended to contain data, so the concept of an array or list which didn't contain any data didn't make sense.

In other words there are a lot of people who have trouble with the concept of "nothing" and wouldn't appreciate the way in which a null object abstracts Java's "null" concept at all.


This reminds me of Sartre's "Being and Nothingness". Let's say you're at a Starbuck's and you expect to meet a friend but she doesn't show. That is a different situation than going to the same Starbuck's NOT expecting to see any friends and indeed having none show up. In the one case, the expectation of having your friend join you creates the dichotomy of either success or failure to appear. i.e. the being or not-being of your friend at Starbuck's. On the other hand, if you have no preconceived expectations, then there is no expected state of being for her not-being to be a contrast to.

To relate this to the "null list versus empty list" debate, you could say that the list is analogous to your expectations and should be instantiated when you start having any sort of expectations, no matter how slight, that there may be elements to put in the list. The list would then be populated with all the friend elements that satisfied your expectation. So in the case where you expect your friend to appear, you would have a non-null empty list. I think that expresses reality better than having a null "expectation" list variable, which would imply that you have no expectations of any friends appearing.

 
jQuery in Action, 2nd edition
 
subject: Why null is a terrible practice in OOP and Java in particular?