使用StringBuilder的目的,即减少内存。实现了吗?
一点都不。该代码没有使用StringBuilder
正确。 (不过,我认为你错误地引用了它;肯定没有引用id2
and table
?)
请注意,目标(通常)是减少内存churn而不是使用的总内存,以使垃圾收集器的工作变得更轻松。
这会占用与使用 String 相同的内存吗?
不,会导致more记忆搅动不仅仅是你引用的直接连接。 (直到/除非 JVM 优化器发现显式StringBuilder
代码中是不必要的,如果可以的话,将其优化掉。)
如果该代码的作者想要使用StringBuilder
(有支持的论据,但也有反对的;请参阅本答案末尾的注释),最好正确地执行(这里我假设实际上没有引号)id2
and table
):
StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, ");
sb.append(id2);
sb.append(" from ");
sb.append(table);
return sb.toString();
请注意,我已经列出了some_appropriate_size
in the StringBuilder
构造函数,以便它一开始就有足够的容量来容纳我们要附加的全部内容。如果您未指定,则使用的默认大小是16 个字符 http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html#StringBuilder%28%29,通常太小,导致StringBuilder
必须进行重新分配以使自身变得更大(IIRC,在 Sun/Oracle JDK 中,它会将自身加倍[或更多,如果它知道需要更多来满足特定的需求)append
] 每次空间不足时)。
您可能听说过字符串连接will use a StringBuilder
如果使用 Sun/Oracle 编译器进行编译,则在幕后。这是真的,它会使用一个StringBuilder
为了整体的表达。但它将使用默认构造函数,这意味着在大多数情况下,它必须进行重新分配。不过,它更容易阅读。请注意,这是not真实的一个series的串联。例如,这使用一个StringBuilder
:
return "prefix " + variable1 + " middle " + variable2 + " end";
大致可以翻译为:
StringBuilder tmp = new StringBuilder(); // Using default 16 character size
tmp.append("prefix ");
tmp.append(variable1);
tmp.append(" middle ");
tmp.append(variable2);
tmp.append(" end");
return tmp.toString();
所以没关系,尽管默认构造函数和随后的重新分配并不理想,但很可能它已经足够好了 - 并且串联是lot更具可读性。
但这仅适用于单个表达式。多种的StringBuilder
s 用于此目的:
String s;
s = "prefix ";
s += variable1;
s += " middle ";
s += variable2;
s += " end";
return s;
最终变成这样:
String s;
StringBuilder tmp;
s = "prefix ";
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable1);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" middle ");
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(variable2);
s = tmp.toString();
tmp = new StringBuilder();
tmp.append(s);
tmp.append(" end");
s = tmp.toString();
return s;
……这实在是太丑了。
但重要的是要记住,除了极少数情况外,没关系除非出现特定的性能问题,否则优先考虑可读性(这会增强可维护性)。