博客
关于我
Java中String和StringBuilder
阅读量:124 次
发布时间:2019-02-26

本文共 3723 字,大约阅读时间需要 12 分钟。

String、StringBuilder及其在Java中的应用

在Java编程中,String类的行为和特性是开发者需要深入理解的核心概念之一。本文将从String的不可变性、StringBuilder的可变性以及字符串操作的实现机制等方面,探讨这些概念的细节及其在实际开发中的应用。


一、String的对象不可变

String类在Java中是一个final类,这意味着它不能被继承。这一点非常重要,因为它决定了String对象的行为特性——不可变

1.1 String的内部结构

通过查看String类的源码,可以发现String对象内部存储了一个char[]数组,用来保存字符串的每个字符。由于这个数组是私有的,并且String类被final修饰,任何修改操作都无法改变原有的String对象。

1.2 String操作的实现

许多常见的String方法(如substringreplace等)在实现时,都会返回一个新的String对象,而不会修改原有的String对象。例如:

  • substring方法会根据给定的起始和结束索引创建一个新数组,并返回一个新的String对象。
  • replace方法则会创建一个新的字符数组,替换掉指定的字符。

1.3 实例验证

通过以下代码可以验证String对象的不可变性:

public void stringTest3() {    String a = "nihaoshije";    String b = a.substring(0, 4);    System.out.println(b); // niha    System.out.println(a); // nihaoshije}

输出结果表明,原字符串a并未被修改,而是返回了一个新的String对象b


二、StringBuilder的字符可变性

StringBuilder类是一个可变字符串容器,它允许对字符串进行高效的修改操作。与String类不同,StringBuilder的字符是可以被修改的。

2.1 StringBuilder的append方法

StringBuilder类通过append方法来添加字符或String对象。该方法返回的是当前StringBuilder对象本身,表明String对象被修改。例如:

public StringBuilder append(String str) {    super.append(str);    return this;}

实际上,append方法会调用父类的append方法,处理字符串追加操作。

2.2 字符数组操作

StringBuilder内部使用一个char[]数组存储字符。通过反编译可以看到,append方法会先检查数组的容量是否足够,如果不够则扩容。然后调用String类的getChars方法,将字符复制到数组中。

2.3 实例验证

以下代码可以直观地观察StringBuilder的可变性:

public void stringBuilderTest() {    StringBuilder stringBuilder = new StringBuilder("hello");    System.out.println(stringBuilder); // 输出: hello    stringBuilder.append("world");    System.out.println(stringBuilder); // 输出: helloworld}

可以看到,StringBuilder对象在调用append方法后,其内容确实发生了变化。


三、关于字符串相加

在Java中,字符串相加操作(如"hello" + "world")看似简单,却隐藏着深层的实现细节。

3.1 "+"运算符的重载

String类的+运算符是Java中唯一的重载运算符之一。当两个String对象相加时,Java会调用StringBuilderappend方法来高效地构建结果字符串。

3.2 字符串相加的实现

通过反编译可以发现,"hello" + "world"在编译期间会被优化为一个新的String对象。这个优化过程意味着,结果字符串会直接引用池中的常量。

3.3 两种相加方式的区别

  • 直接相加String str = "hello" + "world"。这种方式在编译阶段优化,效率较高。
  • 引用相加String b = "hello"; String c = "world"; String d = b + c。这种方式在运行时通过StringBuilder实现,效率相对较低。

3.4 实例验证

public void stringTest4() {    String a1 = "helloworld";    String a = "hello" + "world";    String b = "hello";    String c = "world";    String d = b + c;    System.out.println(a);    // helloworld    System.out.println(d);    // helloworld    System.out.println(a == d); // false    System.out.println(a1 == a); // true    System.out.println(a1 == d); // false}

输出结果表明,直接相加的字符串和引用相加的字符串在内存中是不同的对象。


四、String、StringBuffer、StringBuilder对比

4.1 执行效率

  • StringBuilder > StringBuffer > String
    StringBuilder在多次修改字符串时的效率远高于String,而StringBuffer的效率也低于StringBuilder。

4.2 线程安全

  • StringBuffer是线程安全的,而StringBuilder不是
    StringBuffer的方法都是同步的,适合多线程环境;而StringBuilder的方法则不具备同步性,需要在多线程环境中谨慎使用。

五、常见面试题目

5.1 字符串比较

String a = "hello";String b = "hello";String a1 = new String("hello");String a2 = new String("hello");StringBuilder c = new StringBuilder("hello");StringBuilder d = new StringBuilder("hello");System.out.println(a == b);   // trueSystem.out.println(a1 == a2); // trueSystem.out.println(c == d);   // falseSystem.out.println(a1.equals(a2)); // trueSystem.out.println(a.equals(c));   // falseSystem.out.println(c.equals(d));   // false

答案: true, false, false, true, false, false

5.2 字符串相加的结果

String a = "hellonihao";String b = "hello" + "nihao";System.out.println(a == b); // true

答案: true

原因:在编译阶段,"hello" + "nihao" 会被优化为 "hellonihao",因此 a 和 b 指向同一个常量池中的字符串。

5.3 字符串拼接的结果

String a = "nihaoshijie";String b = "nihao";String c = "shijie";String d = b + c;System.out.println(a == d); // false

答案: false

原因:字符串相加不会在编译阶段优化,因此 d 是一个新的字符串对象。

5.4 String的intern方法

String a = "hello";String b = new String("hello");String c = a.intern();System.out.println(a == b);   // falseSystem.out.println(c == a);   // true

答案: false, true

原因:intern方法会检查常量池中是否存在等于此字符串的实例。如果存在,则返回该实例;否则,将字符串添加到池中并返回新实例。

转载地址:http://fuuy.baihongyu.com/

你可能感兴趣的文章
Postman还能做Mock?又学了一招!
查看>>
postman进行http接口测试
查看>>
Postman高阶技能:Collection集合批量运行!
查看>>
postMessage跨标签页共享数据
查看>>
QImage对一般图像的处理
查看>>
post为什么会发送两次请求?
查看>>
Post表单提交TextArea的值出现转译乱码问题 - Spring MVC处理表单提交
查看>>
Power BI 中的 Python 可视化需要什么设置?任何特定的 matplotlib 包版本或系统设置?
查看>>
Power BI:如何在 Power Query 编辑器中将 Python 与多个表一起使用?
查看>>
power english (3) main text -emotion mastery - focus
查看>>
POWER ENGLISH (6) - MODEL
查看>>
power english (1) —— passion
查看>>
Power English (1) 原文
查看>>
power English (3)原文
查看>>
POWER ENGLISH(7)- repetition
查看>>
SpringBoot中集成SpringBatch详细解析与实战示例(CSV文件读取十万条数据进行业务处理后写入Mysql数据库)
查看>>
powerbi 一张表在另外一张表中出现的数量_PowerBi之初步学习笔记
查看>>
QGIS怎样设置简体中文以及新建可编辑的多边形的图层
查看>>
PowerBuilder 使用自定义事件触发键盘Enter事件
查看>>
PowerCreatorCMS UploadResourcePic 任意文件上传漏洞复现
查看>>