5
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ Just had another thought, are you concatenating using + or StringBuilder? 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\$ – Lam Chau Oct 3 '12 at 5:30
6
\$\begingroup\$

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

\$\endgroup\$
  • \$\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 Sep 29 '13 at 21:00
3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\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 Oct 1 '12 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 like IsDebuggable and use an intermediary (processor) to do handle it. Then you would implement IsDebuggable 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 Oct 1 '12 at 18:12
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\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 Oct 1 '12 at 17:35
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.