toString() is Evil
Posted by Anders Tue, 24 Jun 2008 22:00:00 GMT
...or some other provocative title.
The good old toString() method, with us since Java 1.0, has at least two different meanings:
- Displaying: How the object should appear to the user, in the GUI, on a web page, etc.
- Inspection: How the object should appear in debug output, logs, debugger tools etc.
Both are in some way “a string representation of the object”. The default implementation in java.lang.Object suggests inspection, e.g. “java.lang.Object@c37f31”, but many APIs, like AWT/Swing, use it for displaying the object to the user.
Problems
- It’s hard to tell which usage is intended when reading the code.
- Debuggers will use
toString(), which can cause confusing side-effects. - Since every object has a
toString(), the IDE’s usage search becomes unusable. - It’s hard to tell if a
toString()method is dead code or not.
In addition, a lot of code implements it when it has a more specific meaning. For instance, generating HTML is better done as toHTML() than as toString().
What Others Do
Ruby solves this differently than Java. There are two methods, inspect() and to_s(), where the default implementation of to_s() in Object uses inspect(). This separates the two intentions, but still has to_s() available on every object.
We can’t do much about java.lang.Object, but we still have options.
Suggestion
Use toString() only for logging and debug output.
If the method has a more specific meaning, communicate that instead, e.g. title() or name().
If the value to display has a specific format you can communicate that instead, e.g. toHTML() or asLeetSpeak().
If the value to display is nothing other than a string, still avoid toString(). Call it something like displayString(), or maybe even asString() to avoid problems.

Hi.. Never seen the def. of toString as "Displaying: How the object should appear to the user, in the GUI, on a web page, etc." what reference do you have for this? Other than that you are absolutely right, if you have a business requirement for a textual rep. of your objs. somewhere make a specific method for it. That's programming 101.. http://firstclassthoughts.co.uk
I think I'm gonna add a mandatory asLeetSpeak() to our coding convention, rly gud id3a.
Kasper, the JTree component uses toString() to display the node names. Not only for inspection.
Actually, that is not exactly right. IIRC, the string representation of Swing objects are also intended for developer debugging (to display the nesting structure of Swing components). Nobody said otherwise. Other than that, the "programming 101" comment is out of place. I found the post insightful.
Erm... Shouldn't the front end really do the markup of the object contents rather than the object itself? What if your object had multiple clients (HTML, XML, Swing, etc, etc), you'd end up having multiple toFoo methods on your object. That's not only clutter, it breaks the separation of concerns principal by having your objects know how they are rendered. Putting the display logic inside the object makes it more brittle, more resistant to change. Say you had a toHTML method on it for page A, then page B comes along that wants the object to write out the markup differently. Convert toHTML to be toHTMLForPageA and add a toHTMLForPageB method? What if its used in multiple places? toHTMLForWhenWeWantToDisplayTheObjectNormally? toString should be used for debugging purposes only. The object contents should be accessed via its accessors and marked up by the front end itself.
BTW, it seems that newlines aren't recognised in comments...