只是介绍了三者概念和区别,三者详细方法可看参考Java API文档,如果对概念比较清晰可直接拉到最后!
一、String介绍
String
String
类代表字符串。Java 程序中的所有字符串字面值(如 "abc"
)都作为此类的实例实现,字面量也是对象。
String底层源码中是存储的char数组(jdk1.8及之前版本,jdk1.9之后底层以byte数组存储),但不管是哪种数据类型数组,在底层源码中都是final关键字修饰的,也就是说只能赋值一次,所以String类创建的变量每次赋值运算会创建新的String对象,由于String提供的大多操作字符串方法返回的都是字符串(一个新对象)。如:
如上,String对字符串的操作常常产生新对象,即浪费时间,也浪费空间。详细存储结构参考:
String创建对象的存储结构
二、StringBuffer和StringBuilder介绍
1、StringBuffer
线程安全的可变字符序列。一个类似于 String
的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
2、StringBuilder
一个可变的字符序列。此类提供一个与 StringBuffer
兼容的 API,但不保证同步。该类被设计用作 StringBuffer
的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer
要快。
3、源码分析
-
String Buffer和StringBuilder都是final修饰,都不能被继承。
-
StringBuffer和StringBuilder都是继承于抽象类AbstractStringBuilder,该抽象类将基础的字符串操作方法都已书写,两个子类只需要实现自己的特色功能,基础操作方法调用父类的。
-
StringBuffer和StringBuilder存储字符串也是以char数组(或byte数组),但都是继承的父类AbstractStringBuilder中的属性,且该属性未被final修饰,所以StringBuffer和StringBuilder可以对已保存字符串对象进行操作而不新建对象。
-
两者方法基本相同,只是StringBuilder没有做同步处理。
-
两者在创建对象时都可以设置缓存大小,其实就是创建保存字符串的数组长度,默认是16字符。如:
StringBuilder sb = new StringBuilder(); //获取缓存容量方法 int i = sb.capacity(); //i = 16 StringBuilder sb = new StringBuilder("abc"); int i = sb.capacity(); //i = 16+3 = 19 StringBuilder sb = new StringBuilder(34); int i = sb.capacity(); //i = 34
三、三者区别
String | StringBuffer | StringBuilder | |
---|---|---|---|
概念 | String是不可变类,每次对字符串操作都生成新的对象,影响执行效率,浪费存储空间 | StringBuffer是可变类,对操作字符串方法进行了同步处理,对字符串操作不会产生新对象,每个对象都有一个对应的缓存区,当存储数据长度超出缓存区容量时会自动扩容。 | StringBuilder是可变类,未对操作字符串方法进行同步处理,对字符串操作不会产生新对象,当存储数据长度超出缓存区容量时会自动扩容。 |
线程安全 | 安全。所有不可变类都是线程安全的 | 安全 | 不安全 |
适用情况 | 只是定义,基本不操作字符串 | 多线程时操作字符串 | 单线程操作字符串 |
运行速度 | 一般情况: | String < StringBuffer < StringBuilder |
(不可变类的意思是创建该类的实例后,该实例的属性是不可以改变的。Java提供的8个包装类和java.lang.String都是不可变类,当创建它们的实例后,其实例的属性不可变)
祝,变得更强!