使用Google Guava的Objects.ToStringHelper

56

我曾经在commons-lang中使用ToStringBuilder.reflectionToString(class)来为简单的DTO实现toString()方法。 现在我正在尝试使用Google Guava代替Apache commons库。 我发现Guava中有Objects.ToStringHelper,但是如果类中有很多成员,则它太冗长了。例如:

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

如果我使用commons-lang,这将简单得多:

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

有没有更好的方法使用Guava来实现toString(),而不是使用commons-lang?

Guava文档


现在越来越多的人尝试使用Lombok而不是Google Guava。 - darw
6个回答

116

我有一个关于Guava的com.google.common.base.MoreObjects.toStringHelper()的小技巧。我在IntelliJ IDEA中配置了它,以便在自动生成toString()方法时使用它。我假设你可以在Eclipse中完成相同的操作。以下是在Intellij中执行此操作的方法:

  • 进入一个类
  • 按下 Alt + Insert 弹出 "Generate" 菜单
  • 选择 toString()
  • 点击 "Settings" 按钮
  • 跳转到 "Templates" 选项卡
  • 创建一个名为 "Guava's MoreObjects.toStringHelper()" 的新模板(我通过复制 "ToStringBuilder" 模板来完成)
  • 将模板更改为:

    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();
    }
    
  • 保存模板,关闭“设置”和“生成toString()”窗口

  • 现在可以在生成toString()方法时选择Guava's MoreObjects.toStringHelper()模板。

当您向类中添加新字段时,只需重新生成toString()方法(IDEA将询问您是否要替换现有的toString()方法)。


15
我认为你可以在Eclipse中做同样的事情。——不,没有机会。 - Sean Patrick Floyd
20
该模板已添加到IntelliJ 12.1中(在版本124.567中),请访问http://youtrack.jetbrains.com/issue/IDEA-90598。 - simon04
很抱歉,我没有生成toString方法的选项。我刚刚更新到了12.6版本。我有以下代码生成选项:{构造函数、Getter、Setter、Getter和Setter、equals()和hashcode()、Override Methods...}。Override Methods toString() 为我提供了当前任何方法的默认模板。这个菜单在哪里? - Groostav
2
你是不是指的是“12.1.6”?当我使用“Alt + Insert”或点击“Code”-->“Generate”时,我会看到以下菜单:http://i.imgur.com/nZPf1Rg.png 。底部的“toString()”打开了“Generate toString()”菜单,您可以从不同的模板中选择。您能否检查一下您的设置中是否启用了“GenerateToString”插件? - Etienne Neveu
1
对于 IntelliJ 13.1.4+,我现在看到默认安装中提供了类似的 toString() 模板。太好了。 - kevinarpe
显示剩余2条评论

32
MoreObjects.toStringHelper旨在帮助您轻松编写具有一致格式的toString()方法,但它允许您控制在toString()中包含哪些字段,并且其性能应与手动编写相当。 reflectionToString输入更短,但它不允许您显式控制包含的字段,并且使用反射。 我不认为这是更好的选择。作为副产品,我认为如果每行放一个add调用,则使用toStringHelper看起来更加清晰。

Guava文档


11

有一个插件http://sourceforge.net/projects/guavaeclipse/(非常小)可以使用Guava类生成toString方法(以及equals和hashcode方法)。这是一个不错的解决方案,因为生成的方法非常简短,不会使类变得混乱。


只是需要澄清一下:这个插件并不完美 - 例如无法为嵌套类生成toString方法,但是无论如何,在90%的情况下,这已经足够好了。 - marek.dominiak
嗯...我可以想办法做到这一点...只需选择内部类的名称并继续前进... - Michael Z

6

值得注意的是,Objects.toStringHelper已被弃用(将在2016年6月完全删除),建议使用MoreObjects.toStringHelper。我已经将默认的Guava模板从我的Intellij IDE复制到一个新的模板中,该模板使用MoreObjects替代。干杯。

Guava文档


3

在可用的Eclipse插件中,guavaeclipse仍在使用MoreObjects.toStringHelper,但Jenerate使用MoreObjects.toStringHelper,并且运行得非常顺畅。

Guava文档


你能详细解释一下这如何有所帮助吗? - Cristik
顶部被接受的答案讨论了如何使用IntelliJ生成MoreObjects.toStringHelper toString方法,但对于众多Eclipse用户来说没有用处。其他回答提到了guavaeclipse插件,所以我尝试了一下,但它使用了已弃用的Objects.toStringHelper。然后我偶然发现了Jenerate,它可以工作,所以我想分享一下。 - James
谢谢您的解释,您能否将其添加到答案中,以便更加明显? - Cristik
嗨,感谢您提供有关MoreObjects的提示。GuavaEclipsePlugin从1.4.0版本开始支持MoreObjects。请访问https://guavaeclipsehelperteam.github.io/进行查看。 - Alex

1
在Eclipse中,您可以创建一个模板(不像IntelliJ那样强大https://dev59.com/1Wox5IYBdhLWcg3wFAfW#9445402)。它不会自动遍历所有成员字段,但至少可以得到周围的代码。 Windows > Preferences > Java > Editor > Templates
${:import(com.google.common.base.MoreObjects)}
@Override
public String toString() {
    return MoreObjects.toStringHelper(this)
    .add("${field}",${field})
    .toString();
}

这将添加导入,如果您输入id作为字段,则会得到类似于此的内容。然后由您添加其余字段。
public String toString()
{
    return MoreObjects.toStringHelper(this).add("id", id).toString();
}

请注意,可能有更好的解决方案,可以使用Eclipse的toString()生成器并创建自定义的toString()构建器。但这对于像我这样的懒人来说太麻烦了。
右键单击,然后选择“源>生成toString()”,在代码样式中选择自定义toString()构建器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接