String,StringBuilder 以及 StringBuffer 这三个类的关系与区别一直是 Java 的经典问题,此次就来说一下关于这三个类的一些知识数组
String 属于常量类型,被声明为 final class,全部的属性也都是 final 类型,所以 String 对象一旦建立,便不可更改; StringBuilder / StringBuffer 两个类属于变量类型,是能够更改的,它们都是为了解决字符串因为拼接产生太多中间对象的问题而提供的类。安全
运行速度 StringBuilder > StringBuffer > Stringbash
线程安全: StringBufferapp
非线程安全 : StringBuilder函数
StringBuilder 在本质上和 StringBuffer 没有太大区别,可是因为 StringBuilder 去掉了 StringBuffer 拥有的线程安所有分,所以有效减小了开销。所以,StringBuilder 是大部分状况下字符串拼接操做的首选性能
String s = "abcd";
s = s + "fgh";
复制代码
不少人做这样的字符串处理的时候会误认为 String 类型是可变的。优化
但其实 JVM 处理这段代码的过程是这样的:首先建立 s 对象,赋值“abcd” ,而后处理第二行代码时,再建立一个 s 对象,赋值 “abcdfgh”,而后将第一个 s 对象垃圾回收。ui
因此至关于第一个 s 没更改过,第二个 s 是新的对象spa
String str = “This is only a” + “simple” + “test”;
复制代码
这段代码至关于 String str = “This is only a simple test”;
线程
String str2 = "This is only a";
String str3 = "simple";
String str4 = "test";
String str1 = str2 +str3 + str4;
复制代码
这段代码一样会按照例一的过程来处理
这两个对象在构造的过程当中,首先按照默认大小申请一个字符数组(char[]), 默认容量为 16 个字符,但若是超出,会使用 Arrays.copyOf() 成倍扩容 16,32,64, 128...,固然这样会影响性能,所以能够在建立对象时按照须要自定义其容量
源代码:
//默认 16 个字符
public StringBuilder() {
super(16);
}
//构造函数定义容量
public StringBuilder(int capacity) {
super(capacity);
}
复制代码
咱们都知道,进行字符串拼接操做时推荐使用 StringBuilder,可是是否是何时都推荐使用 StringBuilder 来代替 String 进行字符串拼接?显然不是的。
String str = "123";
String str1 = str + "456";
String str2 = new StringBuilder().append(str).append("def").toString();
复制代码
在这种状况下,两种处理方式效率差异不大
在 JDK1.5 以后, String 的字符串拼接操做会被编译器自动转换为 StringBuilder 并调用 append 方法,最后调用 StringBuilder 的 toString 方法返回一个从新建立的字符串,因为这样的优化方案,使得两个类在这种状况下的处理效率差异不大;而在 Java 9 中,为了更加统一字符串操做优化,提供了 StringConcatFactory,做为一个统一的入口,更加优化了字符串拼接操做。
String str = "";
for (int i = 0; i < 1000; i++) {
str += "12345";
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
stringBuilder.append("12345");
}
复制代码
这种状况下,StringBuilder 更快
在循环中,每执行一次 “+”,都会建立一个 String 对象,所以会有大量对象建立和回收的消耗。
简单来讲,在循环中对同一个字符串对象作字符串拼接,优先选择 StringBuilder
String str1 = "123" + "456" + "789";
String str2 = new StringBuilder("123").append("456").append("789").toString();
复制代码
这种状况下,String 更快
咱们都知道 String str1 = "123" + "456" + "789";
实际上是等同于 String str1 = "123456789";
的,而 StringBuilder 反而须要屡次调用 append 方法。