This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
This seems like it should be obvious, but I can't decide the best way to handle this.
Suppose I have a class with a String instance variable that represents an optional field. How should I write the "get" method for that variable?
Specifically, if that field has no value, do I allow "get" to return a null reference and make the caller of that method deal with it? Or should I return an empty String instead? And if I'm returning an empty String, then should I just initialize the variable to an empty String to begin with?
No matter what I return to indicate "no data," the caller is going to need to know how to interpret that, so maybe null actually is okay...
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
The important question is whether "" ever represents valid data. If not, then returning "" instead of null makes great sense. If, on the other hand, you find yourself saying "Oh, that returned "", now I need to check this other thing to see if data was actually entered or not..." then just using null would be fine.
You're basically talking about using the Null Object Pattern. The discussion in Martin Fowler's book is nice; I wish I could link to it, as much of the material at C2 (the link above) has decayed badly over time. If you've got "Refactoring", look it up.
I guess I would prefer to return an empty String (which is not valid data in this situation) rather than a null reference, because I want to minimize the possibility of a NullPointerExeption. This is how I have it now, with the caller checking whether length is greater than zero.
So here's the next question: If I have a lot of these variables, is there any "savings" in leaving them with a default null initialization, and then just returning an empty String if "get" is called? Or should I actually set these to an empty literal?
I expect that String is a special case in which either approach would be fine, because all the variables would be pointing to the same empty String object in the String pool. But if this were some other type of object, like an array, then it seems that the first option would be better. The potential problem I see is that the get method is returning an object reference when, in fact, the corresponding variable is set to null. But if this object is just a flag for "no data," then it seems okay...
Note: My above example might not be very good; because unlike Strings, arrays are mutable, so actually returning a reference to the object itself (rather than a copy) would violate encapsulation.
It's just a rough sketch to illustrate this "instantiate on demand" concept within the "get" method. (I didn't include the "private" modifiers either.) Hopefully you get the idea. Pretend these are Integer objects if you like...
No way man. NullPointerException is not a valid complaint. I don't see how returning null can increase the potential for that. I prefer to return null as its easiest to deal with. No one returned value has more potential for misinterpretation than another.
The only time null can be a problem is when it represents something other than failure. typically your variables default state is null. So you have to make sure it makes sense for something to be null when an error occurs. For instance, you could return null to indicate no money in account, but that could be problematic.
Originally posted by Stuart Ash: ... I think it is worth the effort educating the programmers to deal with null possibilities responsibly. Comments.
Yes, but in my experience, no matter how many times you tell them...
Returning null actually makes perfect sense to me. It's just that I can envision callers "getting" the reference and then failing to check it before trying to use it as a legitimate object. This is why I'm reconsidering this idea now.
Then again, when I look at the bigger picture and ask whose responsiblity it should be to check a reference before using it, I have to say it's the caller's responsibility. If "get" returns null, then it's the caller's problem. So I don't know...
:roll: [ October 28, 2005: Message edited by: marc weber ]
I would return null, because null is valid data. Pretty much the only time I would return an empty string instead of null is if the object were a VO for a database table and the field in question was a VARCHAR column that was NOT NULL.
In my experience, worrying about NPEs are not reason enough not to return null. If the data is null, let it be null.
I would disagree with Barry about returning a null Collection, however. The reason is this: a method that returns a null for a collection means that no Collection exists. However, most of the time (in finder methods), the collection does exist, albeit with no elements. It's a question of semantics.
In short, return null strings, but do not return null collections (unless you mean to).
Piscis Babelis est parvus, flavus, et hiridicus, et est probabiliter insolitissima raritas in toto mundo.