What is the best standard style for a toString implementation?

17,692

Solution 1

Personally, I find the mix of [] and {} not so easy to get an immediate view of the hierarchy.

I like this format (and I've seen it being used in a number of places):

SimpleClassName[prop1=value, prop2=value]
SimpleClassName[prop1=value, prop2=NestedObject[prop3=value]]

There's also the possibility to add an identifier with @, for example the default style for the commons-lang ToStringBuilder does that (using its own example):

Person@182f0db[name=John Doe,age=33,smoker=false]

Solution 2

I think the format produced by Guava's MoreObjects.toStringHelper() is pretty nice, but it's mainly just good to have some consistent format that you use:

public String toString() {
  return Objects.toStringHelper(this)
      .add("prop1", prop1)
      .add("prop2", prop2)
      .toString();
}

// Produces "SimpleClassName{prop1=foo, prop2=bar}"

Solution 3

json syntax seems to fit pretty well since it was designed specifically to represent complex objects as strings

Person = {
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "address": 
    {
        "streetAddress": "21 2nd Street",
        "city": "New York",
        "state": "NY",
        "postalCode": "10021"
    },
    "phoneNumber": 
    [
        {
            "type": "home",
            "number": "212 555-1234"
        },
        {
            "type": "fax",
            "number": "646 555-4567"
        }
    ]
}

Solution 4

Not a direct answer to the question, however below would be a time saver during initial development:

Disclaimer: Apache Commons library is used.

  1. Add a new Eclipse template called xreflect in Java > Editor > Templates; Add below into its pattern textarea:
// ---------- template start ----------- //
${:import(org.apache.commons.lang.builder.EqualsBuilder,org.apache.commons.lang.builder.HashCodeBuilder,org.apache.commons.lang.builder.ReflectionToStringBuilder)}
/*
 * (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
 */
@Override
public boolean equals(
        final Object pObj) {
    return EqualsBuilder.reflectionEquals(this, pObj);
}

/*
 * (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
    return ReflectionToStringBuilder.toString(this);
}

/*
 * (non-Javadoc)
 * @see java.lang.Object#hashCode()
 */
@Override
public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
}
// ---------- template end ----------- //
  1. Give OK, OK
  2. Just go to the end of a Java class, type xreflect and press Ctrl + Space to autofill equals(), toString() and hashCode() methods automatically.

Solution 5

Is there any standard, or simply just a best practice for a style?

No. The "best" output for a toString() method is determined by what you want to use it for. Is it for serializing the object state in a form that allows it to be deserialized? Is it for creating debug messages? Is it for rendering the object for display to end-users?

(Note that in Java, the toString() method can be used for either purpose. Using toString() for / in end-user messages has problems ... but people do it anyway.)

If you want to develop an in-house style for your debug/logging toString() methods, that's fine. But unless there was a requirement for this, I wouldn't bother. IMO, it is effort that could better be spent elsewhere.

Share:
17,692
Nicole
Author by

Nicole

Full stack software engineer. I've mostly used Java, Python, C, Javascript, HTML/CSS, and SQL. I work remotely and live in Utah with my beautiful girlfriend Kerstin (with whom I try to talk about software engineering as little as possible) and our kids. I'm a passionate feminist and social change activist.

Updated on June 05, 2022

Comments

  • Nicole
    Nicole almost 2 years

    We have a lot of objects for which we like to implement a simple toString to output attributes of the object. Some of these attributes may be complex objects themselves.

    Is there any standard, or simply just a best practice for a style? I'm thinking something like:

    [SimpleClassName] { prop1:value, prop2:value }
    

    In which case a nested value would look like:

    [SimpleClassName] { prop1:value, prop2:[NestedObject] { prop3:value}}
    

    We are using Java but I find myself asking the same question in most languages!

  • zigdon
    zigdon over 13 years
    I think toString should really aim to return a single line, so something like json might be overly verbose.
  • Brad Mace
    Brad Mace over 13 years
    @zigdon - there's no reason you couldn't condense it into a single line
  • Nicole
    Nicole over 13 years
    I like it, but any idea how this meshes with toString used by various frameworks and other open source projects?
  • zigdon
    zigdon over 13 years
    Right, but it would still be fairly verbose on large nested objects.
  • G. Demecki
    G. Demecki over 9 years
    +1, Good to know that eclipse by default generates toString method in that format.
  • Matthew Cornell
    Matthew Cornell about 8 years
    I like this one, though a variation I prefer is like the Java Tutorial where they do not put spaces after commas. While it's more dense, it has the advantage of being able to see strings without having to add quote chars, if that makes sense. Class.getSimpleName() is useful instead of hard-coding, as is Arrays.toString() for array-based variables.
  • JojOatXGME
    JojOatXGME almost 4 years
    The linkt to the default style seems to be dead.