• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Encapsulation and "getting" null references

 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...

:roll:
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15482
43
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An empty string is not the same as null, ofcourse. If an empty string is a valid, non-empty value, then you can obviously not use it to indicate that the string has no value.

Using null makes sense, but you should document your code (Javadoc) to make clear to the user of your method that null is used that way.

If you do want to use empty string as the "empty" value, I would also initialise the string with it.
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jesper de Jong:
An empty string is not the same as null, of course...

Exactly.

My main hesitation is in returning null references, because this opens the door for null pointer exceptions later (even if that behavior is well documented).

The empty String would just be an object state representing "no data." Is that reasonable, or is there a better way to handle this?
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A similar choice is made when returning an array - do we return null or an empty array: new String[0] for instance?

I would guess it's important to be consistent: return empty Strings (these are empty char arrays) and empty arrays, or null String references and null array references.

Oh yes, guaranteed returning of empty Strings and empty arrays enables the caller to check for zero length.
[ October 27, 2005: Message edited by: Barry Gaunt ]
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the replies!

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...

Does that make sense?
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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...

:roll:
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Stuart Ash
Ranch Hand
Posts: 637
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by marc weber:

Exactly.

My main hesitation is in returning null references, because this opens the door for null pointer exceptions later (even if that behavior is well documented).

The empty String would just be an object state representing "no data." Is that reasonable, or is there a better way to handle this?


IMO, return of null should not inhibit you from using that approach. When used by responsible programmers, nulls returned in such cases is actually a help than a hindrance.

I think it is worth the effort educating the programmers to deal with null possibilities responsibly. Comments.
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Joel McNary
Bartender
Posts: 1840
Eclipse IDE Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic