String、StirngBuffer、StringBuilder的区别?
类型 | 可变性 | 线程安全性 | 性能分析 |
---|---|---|---|
String | 不可变 | String是不可变的那自然没有线程安全的讲究 | 在字符串的拼接上面,两者都是比String更快。 |
StirngBuffer | 可变 | 线程安全 (Synchronized修饰) | |
StringBuilder | 可变 | 线程不安全 | StringBuilder 的性能要远大于 StringBuffer。 |
StringBuffer线程安全,StringBuilder线程不安全,底层实现上,其实StringBuffer就是比StringBuilder多加了Synchronized修饰
既然 StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,所以毫无疑问,StringBuilder 的性能要远大于 StringBuffer。然后在字符串的拼接上面,两者都是比String更快的存在,通过分析jvm解析class所产生的字节码,会发现String的拼接其实是每次都产生新的StringBuilder对象然后toString返回String,因为底层也会对String的效率方面做考虑。所以多次的对象创建拼接,自然而然是比不过只创建一次对象的。
这里应该会有小伙伴好奇,为什么String是不可变呢?不可变对象的意思就是说:不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。
String不可变是因为: 1、字符串常量池的需要,如果字符串可变,改变一个对象会影响到另外一个独立的对象。不变这也是字符串常量池存在的前提条件。
【java基础|String、StirngBuffer、StringBuilder的区别《区别|CSDN创作打卡》】2、Java中String对象的哈希码被频繁地使用,比如在HashMap等容器中。不变性也保证了hash码的唯一性,不需要重新计算,这就让字符串很适合作为Map的键。
3、安全性,确保String在当做参数传递时保持不变,避免安全隐患。比如在数据库用户名、密码、访问路径等传输过程中的保持不变,或者在socket编程中主机名和端口名都是以字符串形式传入的,因为字符串是不可变,所以它的值也是不可变的。防止黑客们可以钻到空子改变字符串的指向的对象值造成安全漏洞。
/**
* @author hwx
* @date 2022/1/16 - 14:51
*/
// 安全性,确保String在当做参数传递时保持不变,避免安全隐患
public class test {
public static String appendStr(String s) {
s = s + "bbb";
return s;
}
public static void main(String[] args) {
//String做参数
String s= "aaa";
test.appendStr(s);
System.out.println("String aaa >>> "+s);
//String aaa >>> aaa
//因为Java对象参数传的是引用,所以不可变的的String参数就被没有改变。
}
}
4、由于字符串变量不可变,在多线程中可以被共享使用。这样就不用因为线程安全问题而使用同步。
使用场景 (1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。如果是单线程场合 StringBuilder 更适合。
推荐阅读
- JAVA基础之集合(二)
- java基础|Java方法重写与重载的区别
- Java程序设计|Java——集合
- 1|java基础--5HashMap专题
- #|蓝桥杯31天冲刺打卡题解(Day6)
- 蓝桥杯|蓝桥杯AcWing学习笔记 6-1双指针的学习(附相关蓝桥真题(日志统计、完全二叉树的权值))
- #|蓝桥杯31天冲刺打卡题解(Day2)
- #|蓝桥杯31天冲刺打卡题解(Day1)
- angularjs|安装angularjs及idea导入angularjs项目