假设字符串a和b:
a += b
a = a.concat(b)
在引擎盖下,它们是一样的吗?
这里是concat反编译作为参考。我希望能够反编译+操作符以及看看它做什么。
public String concat(String s) {
int i = s.length();
if (i == 0) {
return this;
}
else {
char ac[] = new char[count + i];
getChars(0, count, ac, 0);
s.getChars(0, i, ac, count);
return new String(0, count + i, ac);
}
}
为了完整起见,我想补充一下,'+'操作符的定义可以在JLS SE8 15.18.1中找到:
如果只有一个操作数表达式为String类型,则String
在另一个操作数上执行转换(§5.1.11)以生成一个
字符串。
字符串连接的结果是对string对象的引用
这是两个操作数字符串的连接。的字符
在右操作数字符的前面
新创建的字符串中的操作数。
String对象是新创建的(§12.5),除非表达式是
常量表达式(§15.28)
关于实现,JLS说了以下几点:
An implementation may choose to perform conversion and concatenation
in one step to avoid creating and then discarding an intermediate
String object. To increase the performance of repeated string
concatenation, a Java compiler may use the StringBuffer class or a
similar technique to reduce the number of intermediate String objects
that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the
creation of a wrapper object by converting directly from a primitive
type to a string.
因此,从“Java编译器可能使用StringBuffer类或类似的技术来减少”判断,不同的编译器可以产生不同的字节码。
为了完整起见,我想补充一下,'+'操作符的定义可以在JLS SE8 15.18.1中找到:
如果只有一个操作数表达式为String类型,则String
在另一个操作数上执行转换(§5.1.11)以生成一个
字符串。
字符串连接的结果是对string对象的引用
这是两个操作数字符串的连接。的字符
在右操作数字符的前面
新创建的字符串中的操作数。
String对象是新创建的(§12.5),除非表达式是
常量表达式(§15.28)
关于实现,JLS说了以下几点:
An implementation may choose to perform conversion and concatenation
in one step to avoid creating and then discarding an intermediate
String object. To increase the performance of repeated string
concatenation, a Java compiler may use the StringBuffer class or a
similar technique to reduce the number of intermediate String objects
that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the
creation of a wrapper object by converting directly from a primitive
type to a string.
因此,从“Java编译器可能使用StringBuffer类或类似的技术来减少”判断,不同的编译器可以产生不同的字节码。
Niyaz是正确的,但同样值得注意的是,特殊的+运算符可以被Java编译器转换为更有效的东西。Java有一个StringBuilder类,它表示一个非线程安全的可变String。当执行一系列String连接时,Java编译器会静默地进行转换
String a = b + c + d;
into
String a = new StringBuilder(b).append(c).append(d).toString();
这对于大字符串来说效率更高。据我所知,使用concat方法时不会发生这种情况。
然而,concat方法在将空字符串连接到现有字符串时效率更高。在这种情况下,JVM不需要创建新的String对象,只需返回现有的String对象。请参阅concat文档来确认这一点。
所以如果你非常关心效率,那么你应该在连接可能为空的字符串时使用concat方法,否则使用+。然而,性能差异应该可以忽略不计,您可能永远都不应该担心这一点。