为何String不可变,String的运算符重载

String运算符重载、String不可变原因

为何 String 不可变

  • java8 之前,String 的源码中是用字符数组实现的,同时使用了 final 和 private 修饰,被 final 修饰的结果就是变量不可修改、类不可继承、方法不可重写,被 private 修饰就无法对外暴露,这就是为何 String 不可变。
  • java8 之后,String 改成了用字节数组实现
  • 新版的 String 其实支持两个编码方案:Latin-1 和 UTF-16。如果字符串中包含的汉字没有超过 Latin-1 可表示范围内的字符,那就会使用 Latin-1 作为编码方案。Latin-1 编码方案下,byte 占一个字节(8 位),char 占用 2 个字节(16),byte 相较 char 节省一半的内存空间。JDK 官方就说了绝大部分字符串对象只包含 Latin-1 可表示的字符。

String 的运算符重载

Java 语言本身并不支持运算符重载,"+“和”+=“是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的运算符。

1
2
3
4
String str1 = "he";
String str2 = "llo";
String str3 = "world";
String str4 = str1 + str2 + str3;

可以看出,字符串对象通过”+“的字符串拼接方式,实际上是通过 StringBuilder 调用 append() 方法实现的,拼接完成之后调用 toString() 得到一个 String 对象 。

不过,在循环内使用”+“进行字符串的拼接的话,存在比较明显的缺陷:编译器不会创建单个 StringBuilder 以复用, 意味着每循环一次就会创建一个 StringBuilder 对象,会导致创建过多的 StringBuilder 对象

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//在循环内使用+号每次都会创建新的StringBuilder
String[] arr = {"he", "llo", "world"};
String s = "";
for (int i = 0; i < arr.length; i++) {
    s += arr[i];
}
System.out.println(s);

//避免了上述问题
String[] arr = {"he", "llo", "world"};
StringBuilder s = new StringBuilder();
for (String value : arr) {
    s.append(value);
}
System.out.println(s);
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计