String
源码如下:public final class String implements java.io.Serializable, Comparable<String>, CharSequence{
/** The value is used for character storage. */
private final char value[];
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
......
}
由源码可知,String中存储数据的数组被关键字final
修饰,因此是不可变的//方式一
String str = "abc";
//方式二
String str = new String("abc");
两种方式都会在栈中创建一个字符串变量str
,但它们的内存分配方式是不同的。 String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str1 == str2); //true
System.out.println(str3 == str4); //false
为了理解这部分内容,最好先了解一下Java中的内存分配机制,可参考此篇博客:【后端面经-Java】JVM内存分区详解常量池
一开始均在方法区中,后来运行时常量池
转移到堆中,下文均按照这种内存分配模型来讨论。abc
,如果找到,则指向这个字符串,如果没有找到,在运行时常量池
中创建这一字符串,然后指向它。str1
和str2
指向的是同一个字符串,即同一个内存单元,所以str1 == str2
为true
str3
和str4
指向的是两个不同的内存单元,所以str3 == str4
为false
StringBuffer
或StringBuilder
来进行字符串拼接。synchronized
关键字,保证线程安全。StringBuffer
和StringBuilder
的重要区别之一。append()
:在字符串末尾添加新字符串;insert()
:在指定位置插入新字符串;toString()
:将StringBuffer
转换为String
;StringBuffer
一样,StringBuilder
源代码中数组是可变长度的。synchronized
关键字,因此线程不安全。StringBuilder
的性能比StringBuffer
略高。String
类;StringBuilder
和StringBuffer
进行初始化,避免频繁扩容,提升性能。 StringBuilder sb = new StringBuilder(100);
StringBuffer sb = new StringBuffer(100);
``
下图是对三者进行的比较:
Q:简单介绍一下String和StringBuilder的区别
A:首先,String定义的字符串是不可变的,使用拼接函数或者操作符将会创建一个新的String对象,性能不高;而StringBuilder定义的字符串可变,且线程不安全使得其具有较好的性能,在字符串需要频繁修改的场景下,使用StringBuilder会更好。