June 21, 2003
The abuse and over-use of toString()

This one is sneaky.. most programmers when writing debug code tend to call the toString() method on an object to retrieve human-readable information and present it to the user in some shape or form (logs, system out, etc). That's good programming.. when debugging a problem we want to be able to read and view all information possible..

Here is the sneaky part.. you should never *never* call toString() on a Java object unless you're pretty damn sure that object will never be null. Why? It's simple.. calling toString() on a null object will generate our good old friend -- the null pointer exception. (What? Java has no pointers! -- wrong!). This is a huge problem.. Think about it.. where do we usually put most of our debugging code? That's right.. error handling.. Something like this, perhaps:

try 
{
   myObject = doSomething();
}
catch (HorribleException e) 
{
   String msg = "Dude, we got us a problem: " + e.getMessage(); 
   msg += "The object looks like this" + myObject.toString();
  
  // do logging and stuff..
  //
} 


If myObject happens to be null, which may very well be the case considering we have an exception while trying to create, modify or reference it it will throw a null pointer exception at which point this becomes a debugging nightmare as the original exception is now lost. Maybe not a huge nightmare in a development environment.. but try to debug issues with code like this in a production environment where all you have to go on is logs and system output. Right.. nightmare.

What should you do instead? Forget toString()! There is a better way of doing it and that's String.valueOf(object) which is implicitly called on calls that convert objects to strings. String.valueOf(object) internally calls toString() on the object -- but it checks for nulls! This is the behaviour you want in your debugging code.. if the object is null you do not want an exception.. just a "null" ought to suffice and the toString() output otherwise..

try 
{
   myObject = doSomething();
}
catch (HorribleException e) 
{
   String msg = "Dude, we got us a problem: " + e.getMessage(); 
   msg += "The object looks like this" + myObject;
  
  // do logging and stuff..
  //
} 


Will generate exactly the same output as the first example when object is fine.. but only the string "null" when object is null. Safer and even less typing! The scary part is how many experienced programmers have no clue about this little gotcha.. go spread the word. Thanks.

Posted June 21, 2003 11:33 AM in Java
TrackBack URL for this entry: http://www.unix-girl.com/mt/mt-tb.cgi/745
Comments
On June 21, 2003 06:45 PM Steve Friedl added:

Wouldn't this be even better? :-)

...
  String msg = "Dude, we got us a problem: " + e.getMessage();
  try {
    msg += "The object looks like this" + myObject.toString();
  } catch ( Exception e ) { }
...

#
On June 21, 2003 06:57 PM kasia added:

Steve..dude.. we've got us a problem :)

#
On June 22, 2003 06:23 AM Starfish added:


Hmmm... I still haven't learned Java.. does that make me the exception? ;-) :-D

#
On June 22, 2003 10:04 AM Lance added:

Thanks Kasia, for reminding me of something I figured out (and forgot) quite some time ago. Such reminders are truly valuable.

#
On June 23, 2003 05:15 AM Frank Merenda added:

Kasia,

Sorry this is a little off topic, it's got to do with searching jar files, not null objects. :)

I am also a java developer, and just wrote an article for uptime about searching tar files. I based it on some scripts that I use to search jar files at work. You can just replace the 'tar' sections with 'jar' and some small changes in the scripts, and you can search jar files in a directory, or recursively, or whatever. It's really handy for searching jar files for contents.

the article, and site and all is all free, of course. I thought you may find it helpful, and I'm sure several of your readers may, also. :)

http://www.steidler.net/uptime/archives/000381.html#000381

Take care-
-Frank Merenda

p.s. the worse is when someone does one of THESE nubmers in a try/catch:

String msg = "You have a problem " + myObject.getSomething().getSomeValueFromThing();

There's always a null in there somewhere.... doh!

#
On June 23, 2003 12:08 PM Tom Copeland added:

PMD - http://pmd.sf.net/ - can catch various problems with Strings, including:

- called "new String("foo");", which creates an unneeded object
- using the same String literal many times in the same class, which is usually a sign that it needs to be refactored to a constant
- calling toString on a String, which is ridiculous

Yours,

Tom

#
On June 25, 2003 12:59 PM Luke Hutteman added:

Or just use String.valueOf(object) which does a null-check internally.

Of course String concatenation calls this method automatically so if that's the context in which you need the String-representation of the object, a "string"+object will work just fine.

Either way, you're absolutely right about not calling .toString() on the object.

Similarly, developers should never write str.equals("literal_value"), but instead always use "literal_value".equals(str) as it will return false instead of throwing a NullPointerException in case str is null.

#
On July 14, 2003 10:47 AM Dave added:

This post is idiotic and overimportant. You shouldn't be calling ANY METHOD on an object unless you know that object isn't null, or you use this wonderful construct called the IF statement.

And, what's wrong with:

System.err.println("Object is: " + (object == null ? "null" : object.toString());

Or

System.err.println("Object is: " + object);

I can't believe what passes for a blog posting these days. In the next installment, be sure to compile your classes before trying to run your program!

#
On July 14, 2003 04:22 PM kasia added:

So Dave, which year CS student are you now? And learn to read your "what's wrong with.." is what I said in this entry..

Psst, it's a blog, nobody makes you read it, go smoke something.

#
Trackbacks
Ted Leung on the air:Promote robust code
Don't use toString().
(read more)
June 21, 2003 03:21 PM
Bill de hÓra:How not to use equals in an if{} block
kasia in a nutshell: The abuse and over-use of toString() The scary part is how many experienced programmers have no clue about this little gotcha.. go spread the word. Yikes.
(read more)
June 22, 2003 12:37 PM
Among Other Things:Two days worth of links
Bill Gates' inbox (from J-Walk)CafePress starts a self-publishing serviceBBSpot: Digital WasteJava programmers: toString() is bad!Teal Sunglasses: Why doesn't my aggregator do this?Macromedia releases Contribute...
(read more)
July 18, 2003 12:33 AM