Es variable
La cadena en el objeto String es inmutable y se define una matriz de caracteres en su clase para almacenar la cadena.
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
StringBuilder 、 StringBuffer 类 图
Se puede ver en su diagrama de clases que ambas clases heredan de la clase AbstractStringBuilder
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
Se puede ver que la matriz de cadenas en AbstractStringBuilder es un valor variable, por lo que StringBuilder y StringBuffer son cadenas variables
Análisis de memoria de cadena: https://zhuanlan.zhihu.com/p/107781993
A prueba de hilos
Los valores de cadena porque es tan constante hilo es la seguridad de
El hilo StringBuilder no es seguro
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
StringBuffer utiliza el método de sincronización sincronizada para lograr la seguridad del subproceso :
@Override
public synchronized StringBuffer append(CharSequence s) {
toStringCache = null;
super.append(s);
return this;
}
Brecha de rendimiento
每次改变String都需要新建一个String并且将引用指向该Sting,因此性能低下
相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险
Sugerencias
- 少量数据:String
- 单线程大量数据:StringBuilder
- 多线程大量数据:StringBuffer
conversión automática de empalme de cadenas javac
源码:
```java
public static void main(String[] args) {
String a = "a";
String b = "b";
String c = a + b;
String d = "a" + "b";
}
```
利用jad工具反编译代码:
```java
public static void main(String args[]){
String a = "a";
String b = "b";
String c = (new StringBuilder()).append(a).append(b).toString();
String d = "ab";
}
```
可以看到当两个字符串“a"和”b"直接执行拼接操作时,javac会自动将其合并,而使用String相加时会自动转换为StringBuilder的拼接