56

I used ToStringBuilder.reflectionToString(class) in commons-lang, to implement toString() for simple DTOs. Now I'm trying to use Google Guava instead of Apache commons library. And I found Objects.ToStringHelper in Guava. But it's too verbose if there're lots of members in the class. For example:

@Override
public String toString() {
    return MoreObjects.toStringHelper(this.getClass()).add("name", name)
            .add("emailAddress", emailAddress)
            .add("department", department).add("yearJoined", yearJoined)
            .toString();
}

is much simpler if I use commons-lang:

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

Is there any better ways to implement toString() with Guava, not with commons-lang?

Guava docs

facundofarias
  • 2,973
  • 28
  • 27
philipjkim
  • 3,999
  • 7
  • 35
  • 48
  • More people are trying to use Lombok instead of Google Guava nowadays https://stackoverflow.com/questions/54604701/how-to-skip-null-field-with-lombok-tostring – darw Jul 27 '20 at 10:34

6 Answers6

116

I have a little trick for Guava's com.google.common.base.MoreObjects.toStringHelper(). I configured IntelliJ IDEA to use it when auto-generating toString() methods. I assume you can do the same in Eclipse. Here's how to do it in Intellij:

  • go inside a class
  • hit Alt + Insert to popup the "Generate" menu
  • choose toString()
  • click the "Settings" button
  • go to the "Templates" tab
  • create a new template named "Guava's MoreObjects.toStringHelper()" (I did it by copying the "ToStringBuilder" template)
  • change the template to:

    public String toString() {
    #set ($autoImportPackages = "com.google.common.base.MoreObjects")
        return MoreObjects.toStringHelper(this)
    #foreach ($member in $members)
        .add("$member.name", $member.accessor)
    #end
        .toString();
    }
    
  • save the template, close the "Settings" and "Generate toString()" windows

  • you can now choose the Guava's MoreObjects.toStringHelper() template when generating toString() methods

When you add a new field to the class, simply re-generate the toString() method (IDEA will ask you to confirm that you want to replace the existing toString() method).

kashike
  • 3
  • 3
Etienne Neveu
  • 12,604
  • 9
  • 36
  • 59
  • 15
    *I assume you can do the same in Eclipse* Nope, no chance. – Sean Patrick Floyd Feb 26 '12 at 16:00
  • Thanks this works fine for me but i'm missing the multiline style of apache commons :'( – Sebastien Lorber Sep 11 '12 at 12:50
  • Very convenient! Thank you! – Murat Derya Özen Jan 14 '13 at 11:36
  • 20
    This template has been added to IntelliJ 12.1 (in build 124.567), see http://youtrack.jetbrains.com/issue/IDEA-90598 – simon04 Apr 17 '13 at 07:07
  • I'm sorry, I don't get the option to generate a toString method. I just updated to 12.6. I've got the options to generate code for: {Constructor, Getter, Setter, Getter and Setter, equals() and hashcode(), Override Methods...}. Override Methods toString() gives me my current default template for any method. Where is this menu? – Groostav Oct 14 '13 at 22:39
  • 2
    Don't you mean "12.1.6"? When I use "Alt + Insert" or click on "Code" --> "Generate", I see the following menu: http://i.imgur.com/nZPf1Rg.png .The "toString()" at the bottom opens the "Generate toString()" menu, where you can choose from different templates. Can you check that the "GenerateToString" plugin is enabled in your settings? – Etienne Neveu Oct 16 '13 at 12:22
  • 1
    For IntelliJ 13.1.4+, I see a similar `toString()` template now available in the default installation. Excellent. – kevinarpe Jul 25 '14 at 13:55
32

MoreObjects.toStringHelper is intended to help you write toString() methods with a consistent format easily, but it gives you control over what fields you include in toString() and should have performance comparable to writing it out manually. reflectionToString is shorter to type, but it doesn't give you explicit control over the included fields and, well, it uses reflection. I don't see it as a better alternative.

As a side note, I think using toStringHelper looks a lot cleaner if you put one add call per line.

Guava docs

facundofarias
  • 2,973
  • 28
  • 27
ColinD
  • 108,630
  • 30
  • 201
  • 202
11

There is a plugin http://sourceforge.net/projects/guavaeclipse/ (really small one) which can generate toString methods (and equals hashcode as well) using Guava classes. This is a nice solution because generated methods are really small and do not clutter the class.

marek.dominiak
  • 113
  • 1
  • 4
  • Just a matter of clarification: This plugin is not perfect - toString methods cannot be generated for the nested classes for example, but anyway, in 90% of cases this is good enough. – marek.dominiak May 20 '12 at 15:59
  • Hmm... I can do this somehow... Just select the name of inner class and go forward... – Michael Z Jul 22 '13 at 21:47
6

It is worth noting that Objects.toStringHelper has been deprecated (to be removed completely in June 2016) in favor of MoreObjects.toStringHelper. I have copied the default Guava template in my Intellij IDE into a new one that uses the MoreObjects instead. Cheers.

Guava docs

Joeri Hendrickx
  • 16,947
  • 4
  • 41
  • 53
Morgan Kobeissi
  • 423
  • 1
  • 5
  • 11
3

Of the available Eclipse plugins, guavaeclipse is still using MoreObjects.toStringHelper, but Jenerate uses MoreObjects.toStringHelper and works like a charm.

Guava docs

facundofarias
  • 2,973
  • 28
  • 27
James
  • 33
  • 2
  • Can you elaborate a little bit more of how this helps? – Cristik May 08 '15 at 06:12
  • The top accepted answer discusses how to generate MoreObjects.toStringHelper toString methods with IntelliJ, but that is of no use to the many Eclipse users out there. Other responses mention the guavaeclipse plugin, so I tried it out, but it uses the deprecated Objects.toStringHelper. Then I stumbled upon Jenerate and it worked so I thought I would share. – James May 09 '15 at 06:33
  • Thanks for the explanation, could you also add it to the answer, where is more visible? – Cristik May 09 '15 at 08:43
  • Hi, thanks for the hint with MoreObjects. GuavaEclipsePlugin supports MoreObjects from version 1.4.0. Please check https://guavaeclipsehelperteam.github.io/ – Alex Jul 14 '15 at 13:36
1

In eclipse you can create a template (not as powerfull as IntelliJ https://stackoverflow.com/a/9445402/1301197 ). It will not loop across all member fields for you but you get at least the surrounding code

windows > preferences > Java > Editor > Templates

${:import(com.google.common.base.MoreObjects)}
@Override
public String toString() {
    return MoreObjects.toStringHelper(this)
    .add("${field}",${field})
    .toString();
}

This will add the import and you will get something like this if you enter id as the field. Then up to you to add the remaining fields.

public String toString()
{
    return MoreObjects.toStringHelper(this).add("id", id).toString();
}

Note that there is probably a better solution by using eclipse toString() generator and creating a custom toString() builder. But this is too much work for a lazy man like me.

Right click then source > generate toString() and select Custom toString() Builder inside code style.

Community
  • 1
  • 1
Ronan Quillevere
  • 3,699
  • 1
  • 29
  • 44