前言
java中用于处理字符串常用的主要三个类
在开发中如何抉择以及在开发岗位中的高频面试题
- String 字符串常量
- StringBuffer 字符串变量(线程安全)
- StringBuilder 字符串变量(非线程安全)
1. 源码
主要的区别在于运行速度和线程安全
1.1 String源码
通过查看sting类的源码
具体解释如下:
- String类表示字符串。 Java程序中的所有字符串字面值,比如“abc”,都是作为这个类的实例实现的。
- 字符串常量; 创建后不能更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,所以它们可以被共享。 例如: String str = "abc";
因此每次String 类型改变的时候等同于生成一个新的 String 对象,生成多一个对象,jvm的gc就会开始工作,速度就会变慢
1.2 StringBuffer源码
通过查看StringBuffer的源码
具体解释如下:
线程安全的、可变的字符序列。 字符串缓冲区类似于string,但可以修改
。 在任何时候,它都包含一些特定的字符序列,但是序列的长度和内容可以通过某些方法调用来改变。- 字符串缓冲区对于多个线程来说是安全的。 这些方法在必要的地方是同步的,
这样,任何特定实例上的所有操作都表现得好像它们是按照某种顺序发生的
,这种顺序与每个涉及的单个线程调用方法的顺序一致。 - StringBuffer上的主要操作是追加和插入方法,
它们是重载的,以便接受任何类型的数据。 它们可以有效地将给定的数据转换为字符串,然后将该字符串的字符追加或插入到字符串缓冲区中
。 append方法总是将这些字符添加到缓冲区的末尾; 插入方法将字符添加到指定的点。 - 每当发生涉及到源序列的操作时(例如从源序列中追加或插入),该类只在执行操作的字符串缓冲区上同步,而不是在源上同步。 注意,虽然StringBuffer的设计是安全的从多个线程同时使用,如果构造函数或追加或插入操作是通过跨线程共享源序列时,调用代码必须确保操作有一个一致的和不变的视图的源序列操作的持续时间。 这可以通过调用者在操作调用期间持有锁来实现,方法是使用不可变的源序列,或者不在线程之间共享源序列。
1.3 StringBuilder源码
通过查看StringBuilder的源码
具体解释如下:
变字符序列。 这个类提供了一个与StringBuffer兼容的API,但不保证同步
。 该类设计用于在字符串缓冲区由单个线程使用的地方(通常情况下)作为StringBuffer的临时替代。 在可能的情况下,建议优先使用这个类,而不是StringBuffer,因为在大多数实现中它会更快。
- StringBuilder上的主要操作是追加和插入方法,它们是重载的,以便接受任何类型的数据。 它们都能有效地将给定的数据转换为字符串,然后将该字符串的字符追加或插入到字符串构建器中。 append方法总是将这些字符添加到构建器的末尾; 插入方法将字符添加到指定的点。
2. 总结
- 运行速度快慢为:StringBuilder > StringBuffer > String
- 操作是多线程的,使用StringBuffer
操作是单线程的,速度比较快的StringBuilder
- 代码示例:
String str="abc";
System.out.println(str);
str=str+"de";
System.out.println(str);
输出结果还是abcde,是因为原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,创建了新的对象赋值,所以速度会变慢
- StringBuffer 带有synchronized关键字,所以才是线程安全。而StringBuillder不带有该关键字,所以不是线程安全