toString(): for debugging or for humans?
class Address
{
private enum Component
{
NUMBER,
开发者_如何学C STREET,
STATE,
COUNTRY
}
private Map<Component, String> componentToValue = ...;
}
I'd like my class to contain two methods:
- One to indicate the value of each address component (so I can debug if anything goes wrong).
- One to return the address in a form expected by humans: "1600 Amphitheatre Parkway Mountain View, CA 94043".
What is the best-practice for Object.toString()? Is it primary meant for #1 or #2? Is there a best-practice for the naming of these methods?
Would you format an address the same way in a SMS message and in an HTML page? Would you format it the same way in English, French and Japanese?
If no, then you have your answer : the presentation does not belong to the object, but to the presentation layer displaying the object. Unless the object is specifically made up for the presentation layer, for example if it is a HtmlI18nedAddress, use toString for debugging.
Consider Date
vs SimpleDateFormat
. Date
contains the state and SimpleDateFormat
returns multiple representations.
I would say the first. Data formatting should not be hard coded into the ToString() function of the object.
I look at it this way: I try to make my ToString() output data that is readable by a matching Parse(string data) function (if that function actually exists or not is not important). So in this case, if you want a specific formatting, write a specific function, and leave the generic data dump routines to ToString().
I normally use the Apache Commons ToStringBuilder http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/builder/ToStringBuilder.html with only the parts that I think are absolutely necessary for debugging.
According to Effective Java Item 12: "Always override toString" the contract for toString()
is:
The result should be a concise but informative representation that is easy for a person to read. [...] providing a good toString implementation makes your class much more pleasant to use and makes systems using the class easier to debug.
Thus, it is for debugging.
More notes on toString()
:
- Add JavaDoc (the format hould be explained here)
- As soon as the format is fixed, keep in mind that the format will be used for parsing.
I highly recommend investing in the book "Effective Java". It is a very nice read. Just five to ten minutes for an item, but your Java live will change forever!
You could read from some debug property that you configure dynamically.:
@Override
public String toString() {
if(debug) {
return debugAddrString()
}
return normalAddrString();
}
ToString should generally only be used for debug information. Keep in mind that you're overriding a method on Object
; is it conceptually accurate to have a method call on an Object
reference return a human readable address? In some cases, depending on the project, this may actually make sense, but it sounds a bit odd to me. I would implement a new method.
Another thing to note is that most modern IDEs use the ToString method to print debug information about objects when inspecting them.
One thing you can do is use a Debug flag to change this as you like:
public String toString(boolean debug) {
if (debug) return debugStringVersion;
else return humanVersion;
}
public String toString() {
return toString(Util.DEBUG);
}
Of course this assumes that you have a utility class suet up with a debug flag in it.
精彩评论