Java 中字符串的支持是通过在 JDK 中提供一个名为 String 的类,对应字符串这个变量类型
String 类的特点
- String 类的底层使用 char 的数组保存数据
- String 类是一个 final 类,不允许被继承
- String 类是一个 immutable 类,该类的对象生成后,内容不会发生变化。该类中的所有返回 String 类型对象的成员方法都是返回一个新的 String 对象
- 方法区中有一块区域名为“常量区”, 用于存储编译时和运行时的字符串常量
String 类方法
String 类作为对应字符串的类,该类中含有大量的方法用来完成字符串相关的构造、裁剪、拼接与替换等功能,大部分为方法重载
创建对象的两种方式
Java 中的字符串对象比较特殊,比普通 Java 类有多一种创建对象的方法,即“字符序列法”1
2String strA = "WiHieree";
String strB = new String("WiHieree");
以上两种方式创建的对象区别:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class StringTest {
public static void main(String[] args) {
String strA = "Wihieree";
String strB = "Wihieree";
System.out.println(strA == strB);
System.out.println(strA.equals(strB));
String strC = new String("Wiyee");
String strD = new String("Wiyee");
System.out.println(strC == strD);
System.out.println(strC.equals(strD));
}
}
//输出结果
true
true
false
true
机制在于JVM内存模型的方法区中有一个 String 常量池(方法去内存),对于使用字符序列方式创建对象,JVM首先会查看字符串常量池中是否已经存在该对象,如果存在,则直接已存在对象而不会新建对象;对于使用 new 运算符方式创建对象,JVM会直接在堆中分配一个新的String对象,如下图所示:
字符串的比较(equals 与 ==)
- 对于 ==,如果作用与基本数据类型(byte、short、char、int、long、float、double、boolean)的变量,则比较的是其存储的“值”是否相等;如果作用与引用类型的变量,则比较其所指向的对象的地址是否相同(即是否同一个对象)。在 Java 中,String 是引用类型
- String的 equals 方法继承自 Java 中的超级父类 Object,Object 的 equals 方法用来比较两个对象的引用是否相等(即是否同一个对象)。但是,String 的 equals 方法不仅是简单地继承,而是进行了重写(Override),用来比较两个 String 对象所存储的字符序列值是否相等
intren 方法
1 | public class StringTest { |
无论是字符串常量区中的 String 对象,还是堆内存中的 String 对象,它们的 intern 方法都是去 JVM 中的字符串常量区获取相等字符序列的 String 对象返回
值传递/引用传递
Java 中只有值传递机制,而没有引用传递机制,所以 String 参数是值传递方式1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class StringTest {
public static void main(String[] args) {
String arg = new String("WiHieree");
change(arg);
System.out.println("main arg ---> " + arg);
}
private static void change(String arg) {
arg = "Wiyee";
System.out.println("chang arg ---> " + arg);
}
}
//输出结果
chang arg ---> Wiyee
main arg ---> WiHieree
字符串与数组之间的转换
字符串不是数组,但是字符串可以转换成数组,反之亦然1
2
3字符 ----> 数组 toCharArray char[] chars = "WiHieree".toCharArray();
数组 ----> 字符 String str = new String(new char[]{'W','i','y','e','e'});
String str = String.valueOf(new char[]{'W','i','y','e','e'});
String、StringBuffer 和 StringBuilder 的区别
对象的可变与不可变
StringBuffer/StringBuilder 类是可以替代 String 类的另一种处理字符串的解决方案,比 String 类更灵活
可以给一个 StringBuilder或StringBuffer 中添加、插入或追加新的内容,但是 String 对象一旦创建,它的值就确定了
效率(使用 StringBuffer 连接字符串)
除了 StringBuffer 中修改缓冲区的方法是同步的之外,StringBuilder 类与 StringBuffer 类是很相似的
如果是多任务并发访问,就使用 StringBuffer ;而如果是单任务访问,使用 StringBuilder 会更有效1
2
3+StringBuilder() 构建一个容量为 16 的空的字符串生成器
+StringBuilder(capacity: int) 构建一个指定容量的字符串生成器
+StringBuilder(s: String) 构建一个带指定字符串的字符串生成器
eg. +append(data: char[]): StringBuilder 将字符串和字符追加到字符串生成器1
2
3
4
5
6
7
8
9
10
11
12
13
14public class StringTest {
public static void main(String[] args) {
StringBuilder a = new StringBuilder();
a.append("Welcome");
a.append(" ");
a.append("to");
a.append(" ");
a.append("WiyeeLu's blog");
System.out.println(a);
}
}
//输出结果
Welcome to WiyeeLu's blog