这个解释最好:在string和stringBuilder之间
参考:Correct way to use StringBuilder
请注意,目标(通常)是减少内存流失而不是使用的总内存,以使垃圾收集器的工作更轻松。
Will that take memory equal to using String like below?
不,它会导致比您引用的直接连接更多的内存流失。 (直到/除非 JVM 优化器发现代码中的显式 StringBuilder 是不必要的,如果可以的话,会对其进行优化。)
如果该代码的作者想要使用 StringBuilder(有支持,但也有反对;请参阅此答案末尾的注释),最好正确执行(这里我假设实际上没有引号id2 和 table):
StringBuilder sb = new StringBuilder(some_appropriate_size);
sb.append("select id1, ");
sb.append(id2);
sb.append(" from ");
sb.append(table);
return sb.toString();
请注意,我在 StringBuilder 构造函数中列出了 some_appropriate_size,以便它开始时有足够的容量来容纳我们要附加的全部内容。如果您不指定一个,则使用的默认大小是 16 个字符,这通常太小,导致 StringBuilder 必须进行重新分配以使其更大(IIRC,在 Sun/Oracle JDK 中,它会增加一倍 [或更多,如果它知道每次空间不足时需要更多来满足特定的附加]。
您可能听说过,如果使用 Sun/Oracle 编译器进行编译,字符串连接将使用 StringBuilder。这是真的,它将使用一个 StringBuilder 来进行整体表达式。但它将使用默认构造函数,这意味着在大多数情况下,它必须进行重新分配。不过,它更容易阅读。请注意,这不适用于一系列串联。例如,这使用了一个 StringBuilder:
返回“前缀”+变量1+“中间”+变量2+“结束”;
大致翻译为:
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();
所以没关系,虽然默认构造函数和后续的重新分配并不理想,但很有可能它已经足够好了——并且串联起来更具可读性。
但这仅适用于单个表达式。为此使用了多个 StringBuilder:
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;
...这很丑。
但重要的是要记住,除了极少数情况外,它并不重要,并且除非出现特定的性能问题,否则优先考虑可读性(增强可维护性)。