目录
二、StringBuffer 和 StringBuilder 讲解
1.StringBuffer 和 StringBuilder 使用场景:(StringBuffer、StringBuilder字符串变量)
3.StringBuffer与StringBuilder的线程安全性问题
三、String、StringBuffer、StringBuilder各指标参数
四、String、StringBuffer、StringBuilder的继承结构
五、String、StringBuffer、StringBuilder在JVM中的原理讲解
3.通过操作码|助忆符|指令 (二进制指令)区别字符串对象的创建方式
七、String、StringBuffer和StringBuilder知识总结
一、String讲解
1.String(String字符串常量)
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象(final修饰), 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢。

我们可以看到,初始String值为“hello”,然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关的操作,就需要使用Java提供的其他两个操作字符串的类——StringBuffer类和StringBuild类来对此种变化字符串进行处理。
2.String 拼接方式与性能的影响
在某些特别情况下, String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:
(1)String对象初始化之前赋值前拼接字符串方式
String S1 = "This is only a" + " simple" + " test";
StringBuffer Sb = new StringBuffer("This is only a").append(" simple").append(" test");
String对象初始值之前进行赋值,拼接字符串方式比较快。
(2)String对象间的字符串拼接方式
String S2 = “This is only a”; String S3 = “ simple”;
String S4 = “ test”; String S1 = S2 +S3 + S4;//调用StringBuilder的toString()方法在堆中创建的String对象
多个String对象间的字符串拼接方式比较慢,因为需要调用stringbuilder的方法在堆中创建新的 string对象。
这时候 JVM 会规规矩矩的按照原来的方式去做。
实例解析:
你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个 String S1 = “This is only a” + “ simple” + “test”; 其实就是:String S1 = “This is only a simple test”; 所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如(2)string对象间的字符串拼接方式:这时候 JVM 会规规矩矩的按照原来的方式去做。
二、StringBuffer 和 StringBuilder 讲解
1.StringBuffer 和 StringBuilder 使用场景:(StringBuffer、StringBuilder字符串变量)
StringBuffer 和 StringBuilder 特点及使用场景:
1>.应用于对字符串进行修改的时候,特别是字符串对象经常改变的情况下。
2>.和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
3>.由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
2.StringBuffer的使用
Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改(可以末尾添加和指定地点添加字符却不能修改)。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer和StringBuilder 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
append():始终将这些字符添加到缓冲区的末端
insert():在指定的点添加字符
实例举例:
如果 z 引用一个当前内容是“start”的字符串缓冲区对象,z.append("le") 字符串缓冲区包含“startle”。同样的“start”, z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。

3.StringBuffer与StringBuilder的线程安全性问题
StringBuffer线性同步,StringBuilder 非线性同步
StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized (同步锁)修饰了。
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
4.synchronized的含义:(线程同步机制)
每一个类对象都对应一把锁,当某个线程A调用类对象中的synchronized方法M时,必须获得对象的锁才能够执行M方法,否则线程A阻塞。一旦线程A开始执行M方法,将独占对象的锁。使得其它需要调用对象的M方法的线程阻塞。只有线程A执行完毕,释放锁后。那些阻塞线程才有机会重新调用M方法。这就是解决线程同步问题的锁机制。
synchronized是java里的一个关键字,可以用来给对象和方法或者代码块加锁,当它锁定一个方法或者代码块的时候,同一时刻最多只有一条线程执行这段代码。
多线程编程中StringBuffer比StringBuilder要安全 。如果有多个线程需要对同一个字符串缓冲区进行操作的时候,StringBuffer应该是不二选择。
注意: 对于String是否安全的说法,String是不可变的。线程对于堆中指定的一个String对象只能读取,所以很安全。
5.String和StringBuffer的效率问题
首先说明一点:StringBuffer和StringBuilder可谓双胞胎,StringBuilder是1.5新引入的,其前身就是StringBuffer。StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。另外,JVM运行程序主要的时间耗费是在创建对象和回收对象上。
我们用下面的代码运行1W次字符串的连接操作,测试String,StringBuffer所运行的时间。
//测试代码
public class RunTime{
public static void main(String[] args){
● 测试代码位置1
long beginTime=System.currentTimeMillis();
for(int i=0;i<10000;i++){
● 测试代码位置2
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-beginTime);
}
}
(1) String常量与String(对象间的拼接)变量的"+"操作比较
▲测试①代码:
(测试代码位置1)
String str="";
(测试代码位置2)
str="Heart"+"Raid";
[耗时: 0ms]
▲测试②代码
(测试代码位置1)
String s1="Heart";
String s2="Raid";
String str="";
(测试代码位置2)
str=

3361

被折叠的 条评论
为什么被折叠?



