30

Is it good or bad practice auto-generating toString methods for some simple classes?

I was thinking of generating something like below where it takes the variable names and produces a toString method that prints the name followed by its value.

private String name;
private int age;
private double height;

public String toString(){
   return String.format("Name: %s Age: %d Height %f", name, age, height);
}
Deepak Gupta
  • 1,075
  • 15
  • 21
Gordon
  • 4,823
  • 4
  • 38
  • 55
  • 1
    What is Formatter? Why not using String.format(String, Object...)? – whiskeysierra Apr 17 '10 at 17:29
  • See also [What are ways to keep hashCode/equals consistent with the business definition of the class?](http://stackoverflow.com/questions/7704038/what-are-ways-to-keep-hashcode-equals-consistent-with-the-business-definition-of) and [Generating equals / hashcode / toString using annotation](http://stackoverflow.com/questions/2535592/generating-equals-hashcode-tostring-using-annotation) – Vadzim Dec 06 '13 at 18:51
  • Auto-generate how: via an IDE / other external tool or via reflection? Reflection specific question: http://stackoverflow.com/questions/1526826/printing-all-variables-value-from-a-class – Ciro Santilli OurBigBook.com Mar 02 '15 at 11:21

9 Answers9

44

Eclipse 3.5.2 (and possibly earlier versions) already provides this feature. If you right-click within the editor, you'll find it under Source -> Generate toString()...

To answer your question about whether it's a bad practice to autogenerate toString(), my opinion is that it is not. If the generated code is very similar to the code you would have written yourself, then why bother typing it out?

Dónal
  • 185,044
  • 174
  • 569
  • 824
  • 1
    As does IDEA since at least version 8 (although you have to enable the option). You do alt-insert while on the class (or right click and choose Generate). – Yishai Apr 16 '10 at 13:45
  • 3
    IMO, this doesn't answer the question - OP is asking if it's *best practice*, and that wasn't mentioned in this answer.. – Jeriko Apr 16 '10 at 14:51
38

I personally like to implement a toString method for all objects, as it helps in debugging.

I would look into using the Apache Commons ToStringBuilder.

You can implement a simple toString method using reflection as follows:

public String toString() {
   return ToStringBuilder.reflectionToString(this);
}

Using this method, you will not have to update your toString method if/when fields are added.

Steve
  • 53,375
  • 33
  • 96
  • 141
  • Though this does have some disadvantages. You have no control over which fields are displayed, and reflection has a reputation for being slow. – Dónal Apr 17 '10 at 23:29
  • @Don - I believe `ToStringBuilder` does offer more methods with fine-grained control. As for performance, just consider when `toString()` is called. Usually it's just when debugging. – ripper234 Jan 04 '12 at 12:40
  • http://stackoverflow.com/questions/3149951/java-tostring-tostringbuilder-not-sufficient-wont-traverse gives an example or recursive use of ToStringBuilder and http://stackoverflow.com/questions/6807771/java-tostring-for-any-object has example AspectJ aspect to implicitly create `toString` in many classes. – Vadzim Dec 06 '13 at 18:37
  • 2
    !!! FYI: Use of reflection makes a function order of magnitude slower. BEAWARE !! – Ajeet Ganga Jun 05 '15 at 22:31
  • @Ajeet No kidding, which is why you don't have logging of this sorts typically enabled in prod. – Steve Jun 09 '15 at 15:47
14

If you use lombok they have a @ToString annotation which will generate the toString for you.

The reason why this is much better to use instead of generating toString with eclipse for instance is that if you later add,remove or change attributes of the class, you will also have to regenerate the toString. If you use lombok you don't have to do that.

Shervin Asgari
  • 23,901
  • 30
  • 103
  • 143
  • 1
    Lombok is also much faster that reflection, supports field exclusion but doesn't allow to alter output style. See also http://stackoverflow.com/questions/3852091/is-it-safe-to-use-project-lombok/3853538#3853538 – Vadzim Dec 06 '13 at 18:30
5

To add to Steve's and Don's answers (+1 for them) :

Make your toString() method simple, make sure it nevers triggers expections (especially be aware of fields that could be null).

If possible, don't call other methods of your class. At least, be sure that your toString() method doesn't modify your object.

And be aware of silly exception-toString loops:

public class MyClass { 
       ... 
       public String toString() { 
          // BAD PRACTICE 1: this can throw NPE - just use field1
            return " field1=" + field1.toString() 
                + " extraData=" + getExtraData();
          // BAD PRACTICE 2: potential exception-toString loop
       }

       public MyExtraData getExtraData() {
           try { 
           .... do something
           } catch(Exception e) {
              throw new RuntimeException("error getting extradata - " + this.toString(),e);
           }

       }

}
leonbloy
  • 73,180
  • 20
  • 142
  • 190
2

In IntelliJ Idea you can press alt+insert, the Generate popup will open; now select the fields and click the OK button; that's it.

Generate Popup by pressing alt + insert

Select Fields and keep the default template as such

the generated to string function

Further tip: In the Generate toString dialog, it gives you a choice to select the template by clicking the drop down on the template combo box. Here you can select StringBuffer if you need to or any other template as required. Play with it to get accustomed. I like it :)

Rajesh Goel
  • 3,277
  • 1
  • 17
  • 13
1

Shortcut to generate toString() method


  1. Press Alt + Shift + S + S (double)
  2. Right click -> Source -> Generate toString() ...
  3. Go to Source menu -> Generate toString() ...
  4. Go to Windows menu -> Preferences -> General -> Keys (Write Generate toString on text field)
Community
  • 1
  • 1
Deepak Gupta
  • 1,075
  • 15
  • 21
0

Be clear when adding toString() as to the audience of the generated text. Some frameworks use the toString() method to generate end user visible text (e.g. certain web frameworks), whereas many people use toString() methods to generate debugging / developer information. Either way, make sure that you have enough uniqueness in the toString implementation to satisfy your requirements.

The default JDK implementation of toString() generates developer info, so that's usually the pattern I recommend if possible, but if you are working on a project with a different idea / expectation you could wind up confused...

Will Iverson
  • 2,009
  • 12
  • 22
0

Just noticed -In NetBeans IDE you can generate toString() method by selecting fields you want to generate it for right click->insert code or use shortcut ALT+INSERT and then select toString().

Way it looks is :

@Override
public String toString() {
    return "ClassName{"+"fieldName="+fieldName+'}';
}

Its great way to debug and no need for additional libs.

Tomas Bisciak
  • 2,801
  • 5
  • 33
  • 57
0

Considering some old answers including @Steve's, I'd like to add answer as per latest library.

Add dependency

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.10</version>
        </dependency>

In your class

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

public class User {
     ... 

     @Override
     public String toString() {
          return ReflectionToStringBuilder.toString(this);
     }
}

You can exclude certain fields as below

    ... 
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toStringExclude(this, "name"); // Name will be excluded from toString output 
    }
Ganesh Satpute
  • 3,664
  • 6
  • 41
  • 78