使用StringBuilder覆盖常见POJO的toString()时,避免内存效率低下

Bru*_*tto 5 java out-of-memory immutability

我正在开发一个项目,我所有的POJO都必须toString()Object class重写中继承.

考虑下面的不可变类:

public final class SomeActivity {
    private final int id;
    private final String name;
    private final String description;
    private final DateTime startDate;
    private final DateTime endDate;
    private final String note;

    // Constructors and getters

    // My future implementation of toString
}
Run Code Online (Sandbox Code Playgroud)

覆盖的目标toString()是实现和输出类似下面的输出(使用所有SomeActivity类字段的测试值):

[Id: 1, Name: Read a book, Description: Trying to discover how to build a plane, StartDate: 17/10/2013, EndDate: 15/11/2013, Note: I really need this]

所以,我有两个解决方案:

1 - 连接字符串

据我所知,这String是一个不可改变的阶级.(请参阅javadoc),因此,如果我实现一个方法来接收这样的输出,我可能会因为我的连接而创建了许多对象:

@Override
public String toString() {
    String s = "[Id: " + id + 
            ", Name: " + name + 
            ", Description: " + description + 
            ", StartDate: " + startDate + 
            ", EndDate: " + endDate + 
            ", Note: " + note + 
            "]";
}
Run Code Online (Sandbox Code Playgroud)

2 - 使用StringBuilder

StringBuilder理论上,使用方法,我将实例化更少的对象而不是"连接方法".但要注意new StringBuildertoString()下面的代码的调用:

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
        builder.append("[Id: ").append(id)
                .append(", Name: ").append(name)
                .append(", Description: ").append(description)
                .append(", StartDate: ").append(startDate)
                .append(", EndDate: ").append(endDate)
                .append(", Note: ").append(note)
                .append("]");

        return builder.toString();
}
Run Code Online (Sandbox Code Playgroud)

第二种选择,真的是最好的吗?或者我应该采用另一种方法吗?考虑toStringloop语句中调用的那些方法.

不幸的是,我对内存测试不是很熟悉,所以如果有可能为此编写测试,我会很高兴知道这一点.

提前致谢.

Jon*_*eet 8

据我所知,String是一个不可变类.(请参阅javadoc),因此,如果我实现一个方法来接收这样的输出,我可能会因为我的连接而创建了许多对象:

不.当您在单个大表达式中执行所有串联时,编译器几乎只需StringBuilder为您创建 - 等效代码.

但请注意下面代码的新StringBuilder和toString()调用:

嗯,是的 - 和?创建一个toString使用各种不同字段值但创建字符串的方法是不常见的.

这里没有内存泄漏.是的,你将创建一个StringBuilderString,但他们会被垃圾收集适当.

随意使用这些形式中的任何一种 - 或者String.format,也许 - 无论您认为哪种形式最易阅读.如果您使用第一个表单,我会重新格式化它以使每行有一个描述和一个字段值:

return "["
    + "Id: " + id 
    + ", Name: " + name 
    + ", Description: " + description
    + ", StartDate: " + startDate 
    + ", EndDate: " + endDate 
    + ", Note: " + note
    + "]";
Run Code Online (Sandbox Code Playgroud)

此时,就可读性和添加/删除字段的简易性而言,它看起来更像是第二种形式.

  • @RichardTingle:重要的是要注意它不是"单独的行" - 它是"单独的语句",这在这里很重要.您可以将单个语句分布在多行上. (2认同)