Sometimes I need toString()
to be quite verbose, normally I don't. It can't be nicely solved by using other methods as toString()
is what gets shown in debugger (and also in the logs unless I call some method explicitly). As nobody should ever rely on its behavior, I wonder if the following is acceptable
public static boolean volatile verboseToString;
public String toString() {
return toString(verboseToString);
}
public String toString(boolean verbose) {
if (verbose) {
return longDescription();
} else {
return shortDescription();
}
}
Is there any better solution?
4 Answers 4
You could try to use Logger level to control verbose mode.
public String toString() {
return toString(logger.isDebugEnabled());
}
public String toString(boolean verbose) {
if (verbose) {
return longDescription();
} else {
return shortDescription();
}
}
Advantage of this approach is that it's easier to control toString() verbosity level - simply by config file for you logging framework, JMX extension, ...
This could also give you more flexibility - based on log level (INFO, DEBUG, TRACE), your could control how much information you put into toString().
-
\$\begingroup\$ This makes sense, although it couples two thing together: the decision if there's an output at all and the the decision how detailed it is. So you can end up with either a long output or none at all. \$\endgroup\$maaartinus– maaartinus2013年09月29日 21:00:58 +00:00Commented Sep 29, 2013 at 21:00
Personally, I use toDebugString()
to prevent misuse for others that may be using this class (or even myself down the line). It has clear intent/purpose (self documenting) without requiring extra thinking to read the javadoc.
On related note, you may find this reference (A collection of "best" java practices) on implementing toString()
helpful as well.
-
\$\begingroup\$ But is there any way to make my debugger use
toDebugString()
? I don't think so, and I don't want to repeat the explicit method call in each logging/debugging statement. I'm afraid I didn't formulate my question clearly enough... \$\endgroup\$maaartinus– maaartinus2012年10月01日 17:39:00 +00:00Commented Oct 1, 2012 at 17:39 -
1\$\begingroup\$ Typically when you're debugging, you'll be using an IDE to step through your code -- debugging vis-a-vis print statements is not good practice since it could be an improper use of the API and thus hidden from your
toString()
method. But, you could also decorate it with an interface with something likeIsDebuggable
and use an intermediary (processor) to do handle it. Then you would implementIsDebuggable
to all classes that you'd want to see as verbose (enforcing a contract) and then use it as such:processClass(IsDebuggable someClass) { someClass.toDebugString(); }
) \$\endgroup\$Lam Chau– Lam Chau2012年10月01日 18:12:52 +00:00Commented Oct 1, 2012 at 18:12
It reminds me Test Logic in Production chapter from the XUnit Test Patterns book.
Effective Java, 2nd Edition, Item 10: Always override toString suggest that,
When practical, the
toString
method should return all of the interesting information contained in the object [...]
So, I'd use the toString
method for only logging and debugging (whether it's verbose or not) and use another methods where specific formats are required.
-
\$\begingroup\$ Sure, the problem is that "all of the interesting information" is actually very long, and sometimes I need "the most important information" only, depending on what I'm currently doing. As an example imagine "class Person". When working with a single person, you may want to see everything; when looking at a list of tens of them, the name alone is nearly too much. \$\endgroup\$maaartinus– maaartinus2012年10月01日 17:35:06 +00:00Commented Oct 1, 2012 at 17:35
I decided that using such a global variable is fine. As nobody should ever rely on the behavior of toString()
, it can't be a problem. Instead of the global public variable I'll use a method so it looks a bit cleaner.
It's ugly, but it does what I need and there's no nice way.
+
orStringBuilder
? It might make a difference if the verbosity is expensive and is constantly being created. But may not be needed as it could be optimized by the compiler. \$\endgroup\$