在Java学习中,String、StringBuffer、StringBuilder三者是很重要的,在编写代码中常常使用到他们,那么深刻的了解他们的异同是很是重要的,接下里咱们详细剖析下这三个的异同之处java
首先总结下这三者的区别:编程
1.基本区别安全
String的对象不可变,StringBuffer和StringBuilder的对象是可变的多线程
2.性能区别app
三者中StringBuilder执行速度最佳,StringBuffer次之,String的执行速度最慢(String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,String对象一旦建立后该对象是不可更改的,后二者的对象是变量是能够更改的)函数
3.安全区别性能
String、StringBuffer是线程安全的,StringBuilder是线程不安全的(因此若是程序是单线程的使用StringBuilder效率高,若是是多线程使用StringBuffer或者String)学习
其次总结下这三者的相同:ui
1.三者在java中都是用来处理字符串的spa
2.三个类都被final修饰,所以都是不可继承的
3.StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)
接下来咱们从源码和案例深刻分析这三者:
1.String
String经常使用方法:
1.length() 获取字符串长度
2.replace() 替换字符串中某些字符
3.equals() 比较两个字符对象内容是否相同
4.substring() 截取一个新的字符串,它是此字符串中的子串
5.trim() 将字符串开头的空白(空格)和尾部的空白去掉
6.indexOf() 求某个字符在字符串中的位置
7.charAt() 求一个字符串中某个位置的值
8.toLowerCase() 将字符串中全部的大写改变成小写
9.toUpperCase() 将字符串中全部的小写改变为大写
注意:
1.String是final类型,不可被继承;
2.String的对象不可变
从上面这个案例咱们发现a对象的内容被改变了,不是说不能改变么,这里咱们不能被表面迷惑,咱们再看下面的程序
咱们发现字符串a被从新赋值后其实已经不是它本身了,从hashCode值能够看出。当a字符串建立赋值maxbill,而后从新赋值时又会建立一个a对象值为:maxbill1993,此时844527467是一已经在等待GC回收了,咱们看到的其实是-1438782163对象。因此咱们在程序中对字符串使用+链接时,并非把内容动态的改变进去,而是每次都会建立一个新的String对象去放新的字符内容,原来的对象会等着GC回收,因此这也是String为啥相比其余二者执行慢的缘由了。
2. StringBuffer
从StringBuffer类的源码能够看出,其方法都被同步锁synchronized修饰,所以是线程安全的,所以在多线程编程中操做字符串是推荐使用为何说StringBuffer比String的执行速度要高,前面说了String的原理,是致使其慢的缘由,StringBuffer相比快是由于使用了字符串变量,是能够动态改变的,没必要像String同样老是去建立对象赋值新内容,咱们
看下面的案例就明白了
由上面的案例能够看出StringBuffer在修改字符串内容时,不会建立新的对象,所以它比String类效率更高
StringBuffer经常使用方法:
1.length() 获取StringBuffer字符长度
2.append() 向StringBuffer增长字符
3.delete() 删除StringBuffer中的字符
4.replace() 替换StringBuffer中的字符
5.insert() 向StringBuffer中插入字符
6.toString () 把StringBuffer转成字符串
StringBuffer的append方法源码解读:
调用了父类的append方法,咱们看下父类append的源码
基本原理:使用append()方法在字符串后面追加东西的时候,若是长度超过了该字符串存储空间大小了就须要进行扩容,构建新的存储空间更大的字符串,将旧的数据的复制过去
详细原理:char value[]用来存储数据,int count用来记录字符长度,StringBuffer初始16个字符容量 ,先记录下传进来字符串的长度,而后使用ensureCapacityInternal函数判是否须要扩容,若是容量不够则使用newCapacity进行扩容,新容量扩为原来2倍+2,存储容量够了使用getChars函数复制数据,最后将count更新。
3. StringBuilder
StringBuilder和StringBuffer的使用方法和原理基本一致的,惟一的区别就是StringBuilder是线程不安全的,执行效率要比StringBuffer高,所以当时单线程的时候推荐使用线程不安全的StringBuilder效率更高一些,若是是多线程推荐使用StringBuffer来保证线程安全