[关闭]
@JeromeLiee 2020-02-11T23:29:08.000000Z 字数 1933 阅读 467

String字符串


参考

java基础:String — 字符串常量池与intern(二)

1. 概述

String 是Java中的一个类,可以用来表示字符串,其内部使用 char 数组来存储数据。

  1. public final class String {
  2. /** The value is used for character storage. */
  3. private final char value[];
  4. ...
  5. }

其中内部存储数据的 char 数组使用 final 来修饰,并且没有提供可修改 char 数组的方法,则表明当 String 对象被创建后,其值是不可变的。

2. String不可变的好处

3. 字符串常量池和intern()方法

字符串常量池保存着所有字符串的字面量,这些字面量在编译期间就已经被确定。不过在运行期间,也可以通过String.intern()方法将一个字符串添加到常量池中。

  1. String s1 = new String("abc");
  2. String s2 = new String("abc");
  3. System.out.println(s1 == s2); // 输出false
  4. String s3 = s1.intern();
  5. String s4 = s2.intern();
  6. System.out.println(s3 == s4); // 输出true

在上述代码中,s1指向了在堆中创建的一个String对象,s2指向了在堆中创建的另外一个String对象,所以它们的地址值不相等,输出false;而接下来通过s1.intern()方法判断字符串"abc"是否在常量池中,是则直接返回,否则创建并返回,所以s3、s4都指向了常量池中同一个"abc"字符串常量,所以输出为true。

4. equals()和contentEquals()方法

  1. String s1 = "abc";
  2. StringBuilder s2 = new StringBuilder("abc");
  3. System.out.println(s1 == s2); // 输出false
  4. System.out.println(s1.equals(s2)); // 输出false
  5. System.out.println(s1.contentEquals(s2)); // 输出false

第一行输出:因为二者为两个不同的对象,地址值不同,所以false;
第二行输出:因为在String的equals()方法中,会先判断二者类型是否相同,不同则为false,而s1和s2一个是String类型一个是StringBuilder类型,所以false;
第三行输出:因为在String的contenEquals()方法中会判断传入参数的类型,如果是StringBuffer或StringBuilder则比较其内部的char数组是否一致,所以输出为true。

5. String、StringBuffer和StringBuilder

String是不可变的,当对String类进行操作的时候,例如拼接等,总会创建新的String对象,比较消耗资源,所以Java提供了两个可以对String进行高效操作的可变工具类——StringBuffer和StringBuilder。

StringBuffer和StringBuilder内部维护了一个可变的char数组,在对字符串操作时,实质上是对这个可变char数组进行操作,在toString()方法会调用String的构造方法,将这个可变的char数组传递过去,创建一个新的String对象。

StringBuffer是线程安全的,因为在其每个操作方法上都加了synchronized关键字,而StringBuilder没有加该关键字,所以是线程不安全的。

6. String “+” 符号的实现

如果是常量、字面量以及基本数据类型变量通过“+” 符号连接的话,会直接被编译成字符串:

  1. String s = "a" + "b" + 1;
  2. // 等同于下面的代码
  3. String a = "ab1";

而如果有String对象参与,则通过StringBuilder进行拼接:

  1. String a = "a";
  2. String b = a + "b" + 1;
  3. // 等同于下面的代码
  4. String a = "a";
  5. StringBuilder builder = new StringBuilder();
  6. String b =
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注