【问题标题】: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.

标签: java php javascript actionscript tostring


【解决方案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 库。

    1. 在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 ----------- //
    
    1. 给OK,OK
    2. 只需转到 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 "SimpleClassName{prop1=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 - 你没有理由不能把它压缩成一行
              • 是的,但在大型嵌套对象上仍然相当冗长。
              猜你喜欢
              • 1970-01-01
              • 2019-08-28
              • 1970-01-01
              • 1970-01-01
              • 2023-03-12
              • 1970-01-01
              • 1970-01-01
              • 2010-10-03
              • 1970-01-01
              相关资源
              最近更新 更多