File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes OO, Patterns, UML and Refactoring and the fly likes Null or Empty object (Return Type) 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 "Null or Empty object (Return Type)" Watch "Null or Empty object (Return Type)" New topic
Author

Null or Empty object (Return Type)

Shivani Chandna
Ranch Hand

Joined: Sep 18, 2004
Posts: 380
There was discussion in my team regarding the return value.

Suppose we have a method
public String[] doSomething(int x)

and on check of boundary condition it should return. They stated that
null should be returned - and there is no point returning empty String[] object (which I had done in my design) citing reasons that an additional object is unneccssarily created.

So I returned what they told me to - > null instead of new String[] and everywhere this method is called , I have to put a check for null....
String[] sarr = doSomething(5) !
if sarr != null

I wanted to ask - Is this right -- to return null instead of empty String[] for the sake of performance ? . Should not null be avoided as a return type since the calller ( if a new one is created ) will not need to be aware that it has to check for null values before using the return output.............

Thanks !
Shivani.


/** Code speaks louder than words */
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

I agree with you. Years ago Kevlin Henney wrote an article for Java Reports describing the Null Method. The key value of return a type that is "consistent" is that you no longer have to treat null as a separate case. I like that.

The downside is your other developers may not get what you're doing, but I find the 'extra object creation' argument specious. Unless there's a high distribution of responses that would return null, I think this is needless worry. I'd rather have a cleaner pattern.

Here's Kevlin's article if you're interested.
[ September 06, 2005: Message edited by: Michael Ernest ]

Make visible what, without you, might perhaps never have been seen.
- Robert Bresson
Vladas Razas
Ranch Hand

Joined: Dec 02, 2003
Posts: 385
You can beat them with JDK. There are many things there that may return empty array.
But hey look at the bright side! You can easily achieve lead developer or architect (whatever they call that) position in that kind of team
Scott Ambler
author
Ranch Hand

Joined: Dec 12, 2003
Posts: 608
Another thing you might want to consider is to throw an exception. Does the boundary condition reflect an important business issue which should be dealt with? If so, throwing an exception may be warranted. If not, send back an empty String as everyone else suggests. Do you really want to check for nulls all over your code? Particularly if it isn't all that common to return a null in the first place?

- Scott


<a href="http://www-306.ibm.com/software/rational/bios/ambler.html" target="_blank" rel="nofollow">Scott W. Ambler</a><br />Practice Leader Agile Development, IBM Rational<br /> <br />Now available: <a href="http://www.ambysoft.com/books/refactoringDatabases.html" target="_blank" rel="nofollow">Refactoring Databases: Evolutionary Database Design</a>
Shivani Chandna
Ranch Hand

Joined: Sep 18, 2004
Posts: 380
Thank You Everybody --for your views on this matter.
It makes me see that - I was not thinking on wrong lines completely....

Scott,an exception has not to be thrown in this case.
Michael - shall read the site link for more info on this matter.

Cheers,
Shivani
[ September 07, 2005: Message edited by: Shivani Chandna ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
See also http://c2.com/cgi/wiki?NullObject for some discussion.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
In short: the costs of the more complex code due to null checks are much higher than the costs of creating an additional object.
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

I love it when I happen to agree with Ilja. Makes me think I've still got some good smarts.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'm late to the party, but let me throw this in. We use a vendor framework and in their docs they suggest you can make a class that runs either in a container managed transaction context or a bean managed transaction like this:

I suggested:

You can guess what NullTransaction does in all those methods. Nothin at all. Far fewer chances to forget the check for null and get a null pointer the one time you wanted to roll back.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Roger Chung-Wee
Ranch Hand

Joined: Sep 29, 2002
Posts: 1683
Let me pose this question: can we say that null IS-A String[]? No! By not returning String[], you have broken the API of the method you have written.

And as others have said, there is a negative impact on clients' code which can get littered with checks for null - just to save a few objects from being created.


SCJP 1.4, SCWCD 1.3, SCBCD 1.3
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15952
    
  19

Null's not the only case. Way back when, we used to return -1 (or 0, for FORTRAN or COBOL) for "not found" index on searches.

In theory, the search function was just like a mathematical function, so would return an index that was in the Range of ordinals. But by returning a value guaranteed to be out of the Range, one essentially flipped from a numeric functionality to a boolean one, since "not found" is not an index, it's a pseudo-index. Or an indication, if you prefer.

In modern times, where performance is not an issue, I'd just as soon throw an Exception, since there's often a chance that not only is the failure case an infrequent one, but also requires radically different handling anyway. For instances where that's not desirable, I settle for minimizing the amount of stuff I have to screw up^W^W code. I hate having to do things like "if ( (s != null) && (s.length()>0))" over and over. Sooner or later, I will end up throwing an Exception in a case like that, but it will end up being the less informative NullPointerException that comes from having buggy code, having forgotten that one last null check.

Sometimes one has to make a distinction between, for example, returning an empty string and a null (think HttpServletRequest.getParameter(), for example). But why beg for trouble?

In particular, I'd rather get back an empty array than a null object for methods that are supposed to return arrays. It corresponds better to an empty collection (null set) and unless I'm mistaken, an empty array can be statically constructed at compile time and shared and recycled without requiring garbage collection, just like String constants.
[ September 08, 2005: Message edited by: Tim Holloway ]

Customer surveys are for companies who didn't pay proper attention to begin with.
Ryan McGuire
Ranch Hand

Joined: Feb 18, 2005
Posts: 1006
    
    3
I think the correct answer to the original question depends on the problem domain meaning of doSomething().

General principle: Zero is just another number.

Just because the returned array would have zero elements, that's no reason to get rid of the String array object itself.

Could there be different meanings implied a null String array and a non-null one with zero elements? Sure. For insance if doSomething is responsible for getting all the transactions for a given customer account. A null String array return value may mean that the specified account doesn't exist, while an empty (but non-null) array would mean the account does exist, but there have been no transactions yet.

So the answer depends on the meaning that you have assigned to the array elements and to the array itself. In many cases a set/group/list with zero elements has completely different meaning from not having the group at all.

Possible point of contention: Should calling getAccountTransactions(String accountNumber) with an (otherwise valid) account number for an account that doesn't exist return a null String array or throw an exception? Which client code would you all rather see:

This:

or this:

Concerning the overhead of creating extra objects "for no good reason"... If the object resides in the same JVM, it's no big deal. But if the object was instantiated on a remote machine (via RMI or whatever), the extra round trip to free an empty String array object (that provided no information that a null return value couldn't have) may incur some non-trivial overhead.
[ September 08, 2005: Message edited by: Ryan McGuire ]
Roger Chung-Wee
Ranch Hand

Joined: Sep 29, 2002
Posts: 1683
I really don't like the idea of returning either String[] or null. If the account does not exist, then I'd throw a FinderException or something similar for the client to handle. Isn't this what exceptions are for?
But if the object was instantiated on a remote machine (via RMI or whatever), the extra round trip to free an empty String array object (that provided no information that a null return value couldn't have) may incur some non-trivial overhead.

I don't know what this means. My remote experience is with EJBs; you won't free anything as the client and server JVMs will garbage collect the String arrays if necessary.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Ryan McGuire:
Which client code would you all rather see:


This:



Of the three code snippets, this one provides the best encapsulation *and* expressiveness.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
I'd agree, but then be a pain the butt ...

account.showYourOwnDarnedTransactions()

might score higher on those scales.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Stan James:
I'd agree, but then be a pain the butt ...

account.showYourOwnDarnedTransactions()

might score higher on those scales.


Just be careful that you don't end up with showYourOwnDarnedTransactionsAsHtml, showYourOwnDarnedTransactionsInADialog, showYourOwnDarnedTransactionsAsPdf...

With other words, if you have a show method on account, make sure that it doesn't know about the exact format.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Yup, been there. Actually I have that in my Wiki. renderAs(HTML) and renderAs(TEXT). A base widget delegates to an appropriate renderer. That bit is stable enough (so far) that it hasn't hurt me (yet). I have in the back of my head that if we ever dump my Wiki for actual supported software I could plug in a renderAs( OTHERWIKIFORMAT ) without much effort.

For this problem

account.renderTransactionsTo( renderer )

would be one way around that. BTW, it occurred to me on my 3 hr drive home last night that account.showTransactions() might be exactly the method we were trying write all along. If so, y'all were way ahead of me.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Roger Chung-Wee:
Let me pose this question: can we say that null IS-A String[]? No! By not returning String[], you have broken the API of the method you have written.

And as others have said, there is a negative impact on clients' code which can get littered with checks for null - just to save a few objects from being created.


Yes null is a String[]. Only a Roman would disagree I think what you are getting at is that an array be definition can contain 0 elements. Thats the 'contract' implied by returning an array (0 or more). So when you find 0 elements you have no right to return null over the 0 length array.




Of the three code snippets, this one provides the best encapsulation *and* expressiveness.[/qb]
</blockquote>


I agree with Ryan. I know where you are coming from Ilja but in your example if you don't lock the source while you are doing your existence check, then the item in question could be deleted just before you make your 'get' call. So using your technique works but requires locking scheme. I recently changed from a null check to the boolean exists() check but then I had to recognize it could still return null so now I'm doing both
[ September 10, 2005: Message edited by: Mr. C Lamont Gilbert ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Yes null is a String[]. Only a Roman would disagree


"null is a String" doesn't have much meaning, simply because "is a" isn't well defined in this context.

According to Liskov's Substitution Principle, null is not a subtype of String[]. Java's instanceof operator knows this, too - null is never an instance of any class.

That you can assign null to a reference to a String[] is more a language hack, in my opinion.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Ilja Preuss:


"null is a String" doesn't have much meaning, simply because "is a" isn't well defined in this context.

According to Liskov's Substitution Principle, null is not a subtype of String[]. Java's instanceof operator knows this, too - null is never an instance of any class.

That you can assign null to a reference to a String[] is more a language hack, in my opinion.


Yes you have a point. null is more of a representation requiring interpretation than anything else. I guess Sun didn't want to be Anal and force everyone to create NullInstances of each type they used to represent nothingness. They left it optional.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Mr. C Lamont Gilbert:

Yes you have a point. null is more of a representation requiring interpretation than anything else. I guess Sun didn't want to be Anal and force everyone to create NullInstances of each type they used to represent nothingness. They left it optional.


And they even might have been right doing so in this case...

I like a feature that is implemented in Nice, though: being able to declare wether a reference is allowed to hold null values. http://nice.sourceforge.net/safety.html#id2448199
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Ilja Preuss:


And they even might have been right doing so in this case...

I like a feature that is implemented in Nice, though: being able to declare wether a reference is allowed to hold null values. http://nice.sourceforge.net/safety.html#id2448199


Is that a runtime or compile time check?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Mr. C Lamont Gilbert:


Is that a runtime or compile time check?


Compile time, if I remember correctly. From what I've read, the compiler even recognizes if you are inside an "if (foo != null)" and allows you to assign foo to non-null references.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Null or Empty object (Return Type)
 
Similar Threads
getting error when converting vector to string
Should EJB not return initialized objects?
collection exercize
Return type problem in function
Help on Hashcode