String类
字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串。
- String类是不可改变的,被final修饰的。所以你一旦创建了String对象,那它的值就无法改变了。
字符串实际上就是一个char数组,并且内部就是封装了一个char数组。 并且char数组是被final修饰的;
并且String中所有的方法,都是对于char数组的改变,只要是对它的改变,方法内部都是返回一个新的String。public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[];
- 字符串常量池(String Constant Pool,简称SCP)
从Java 7开始属于堆空间的一部分(以前是放在方法区) - 当遇到字符串字面量是,会去查看字符串常量池SCP。
如果SCP中存在与字面量内容一样的字符串对象A时,就返回A
否则,创建一个新的字符串对象D,并加入到SCP中,返回D - 通过new关键字来生成的字符串都是在堆区进行,这个字符串中的value存储着字符串常量池中的地址。
String类的常见面试问题
- 以下打印结果为:
打印结果:String s1 = "abc"; String s2 = new String("abc"); System.out.println(s1==s2); System.out.println(s1.equals(s2));
因为s1是字符串字面量,在常量池中,而s2是通过new创建的,在堆中,所以s1和s2地址不同,但是内容相同。false true
- 以下打印结果为:
打印结果:String s1= "a" + "b" + "c"; String s2= "abc"; System.out.println(s1==s2); System.out.println(s1.equals(s2));
因为s1和s2都是字符串字面量,在常量池中。true true
- 以下打印结果为:
打印结果:String s1 = "ab"; String s2 = "abc"; String s3 = s1 + "c"; System.out.println(s3==s2); System.out.println(s3.equals(s2));
先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false。false true
StringBuffer类
字符串变量。在进行字符串操作时,不会返回新的字符串常量。
它的方法都加了synchronized关键字,所以它是线程安全的。
StringBuilder类
字符串变量。在进行字符串操作时,不会返回新的字符串常量。
非线程安全,性能上优于StringBuffer
使用基本原则:
- 如果要操作少量的数据用String;
- 单线程操作大量数据用StringBuilder;
- 多线程操作大量数据,用StringBuffer;