toString 实现的最佳标准样式是啥? [关闭]

Posted

技术标签:

【中文标题】toString 实现的最佳标准样式是啥? [关闭]【英文标题】:What is the best standard style for a toString implementation? [closed]toString 实现的最佳标准样式是什么? [关闭] 【发布时间】:2011-04-26 04:21:46 【问题描述】:

我们有很多对象,我们希望实现一个简单的toString 来输出对象的属性。其中一些属性本身可能是复杂的对象。

是否有任何标准,或者仅仅是一种风格的最佳实践?我在想这样的事情:

[SimpleClassName]  prop1:value, prop2:value 

在这种情况下,嵌套值如下所示:

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

我们正在使用 Java,但我发现自己在大多数语言中都在问同样的问题!

【问题讨论】:

提示:像 Eclipse 这样的 IDE 可以生成 toString()。探索 来源 菜单。节省时间! 我认为真正节省时间的是使用调试器。您可以在任何时候中断执行,然后打印您需要的有关可用对象的所有信息,获取堆栈跟踪,进行所需的任何更改,然后继续。所有这些都不会使用 toString 方法和跟踪使您的代码膨胀。为什么还要麻烦调试器为你做这一切,为每个对象? Java SE7 文档很好地描述了 toString() 应该做什么。 Here. 【参考方案1】:

是否有任何标准,或者仅仅是一种风格的最佳实践?

没有。 toString() 方法的“最佳”输出取决于您要使用它的目的。是否以允许反序列化的形式序列化对象状态?是用于创建调试消息吗?是否用于渲染对象以显示给最终用户?

(请注意,在 Java 中,toString() 方法可用于任一目的。在最终用户消息中使用 toString() 是有问题的……但人们还是会这样做。)

如果您想为您的调试/记录 toString() 方法开发一种内部风格,那很好。但除非有这个要求,否则我不会打扰。 IMO,最好把精力花在其他地方。

【讨论】:

【参考方案2】:

就我个人而言,我发现[] 的组合不太容易立即查看层次结构。

我喜欢这种格式(我已经看到它在很多地方使用):

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

还可以使用@ 添加标识符,例如the default style 用于commons-lang ToStringBuilder 这样做(使用它自己的示例):

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

【讨论】:

我喜欢它,但知道它如何与各种框架和其他开源项目使用的 toString 相结合吗? +1,很高兴知道 eclipse 默认会以该格式生成 toString 方法。 我喜欢这个,虽然我更喜欢的一个变体就像 Java 教程一样,他们不会在逗号后放置空格。虽然它更密集,但它的优点是能够查看字符串而无需添加引号字符,如果这有意义的话。 Class.getSimpleName() 代替硬编码很有用,Arrays.toString() 对于基于数组的变量也是如此。 默认样式的链接似乎已失效。【参考方案3】:

不是对这个问题的直接回答,但是在初始开发过程中,下面会节省时间:

免责声明:使用 Apache Commons 库。

    Java > Editor > Templates 中添加一个名为xreflect 的新Eclipse 模板;在其 pattern 文本区域中添加以下内容:
// ---------- 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 ----------- //
    OK,OK 只需转到 Java 类的末尾,键入 xreflect 并按 Ctrl + Space 即可自动填充 equals()、toString() 和 hashCode() 方法自动。

【讨论】:

【参考方案4】:

我认为Guava 的MoreObjects.toStringHelper() 生成的格式非常好,但使用一些一致的格式主要是好的:

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


// Produces "SimpleClassNameprop1=foo, prop2=bar"

【讨论】:

【参考方案5】:

检查 phps print_r($obj, true) 或者 serialize() 也可以工作,不确切知道它需要什么。 jsons 也是一个干净的解决方案,特别是如果你想在 javascript 环境中导入数据

【讨论】:

【参考方案6】:

既然你问到其他开源项目有哪些,下面是 jEdit 的做法,这与 Wouter 的类似:

BufferChanging[what=BUFFER_CHANGING,source=org.gjt.sp.jedit.EditPane[active,global]]

【讨论】:

【参考方案7】:

如果你的对象有一些可能有用的标识符,我会实现你的第二个例子:

[SimpleClassName:id]  prop1:value, prop2:[NestedObject:id]  prop3:value 

id 是对该对象有意义的标识符 - 规范 Person 对象的名称、数据库中对象的主键等。

【讨论】:

【参考方案8】:

json 语法似乎非常适合,因为它专门用于将复杂对象表示为字符串

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"
        
    ]

【讨论】:

我认为toString 应该真正旨在返回一行,所以像 json 这样的东西可能过于冗长。 @zigdon - 你没有理由不能把它压缩成一行 是的,但在大型嵌套对象上仍然相当冗长。

以上是关于toString 实现的最佳标准样式是啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

解析命令行参数的最佳方法是啥? [关闭]

解析命令行参数的最佳方法是啥? [关闭]

.Net 中 AOP 的最佳实现是啥? [关闭]

为只读结构实现相等的最佳实践是啥? [关闭]

保护 REST API 的最佳方式是啥? [关闭]

实现日历和时间选择器的最佳方法是啥? [关闭]