可变字符串 & 不可变字符串

本文详细解析了Java中的字符串概念,包括String、StringBuffer与StringBuilder的区别及应用场景。重点介绍了它们的底层实现方式,以及在单线程与多线程环境下的选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*
 * 字符串:
 *         一组  字符序列  组成的串
 * 分类:
 *         不可变字符串:String
 *             当前String类创建对象完毕之后,该对象的内容(字符序列)是不能改变的,
 *             一旦改变就会得到(返回)一个全新的String
 *         可变字符串:StringBuffer StringBuilder
 *             当通过Buffer或Builder创建对象完成之后,对该对象内的字符串进行任何修改,
 *             都是在当前字符串内完成,而不会新建字符串
 */

/*
 * StringBufferStringBuilder:
 *         可变字符串,对字符串内容的修改会被映射到原有字符串上
 *         API近乎完全相同
 * 不同点:
 *         StringBuffer是一个线程安全但是效率低的字符串构建器 (synchronized)
 *         StringBuilder是一个线程不安全但是效率高的字符串构建器
 *         在没有多线程的前提下,推荐使用StingBuilder,若需要出多线程使用StringBuffer可以保证线程安全
 */

public class Demo4 {
	public static void main(String[] args) {
		String string = "abc";
		System.out.println(string.hashCode());
		string = "bcd";
		System.out.println(string.hashCode());
		
		StringBuffer stringBuffer = new StringBuffer("abc");
		System.out.println(stringBuffer.hashCode());
		stringBuffer.append("d");
		System.out.println(stringBuffer.hashCode());
		
		StringBuilder stringBuilder = new StringBuilder("abc");
		System.out.println(stringBuilder.hashCode());
		stringBuilder.append("d");
		System.out.println(stringBuilder.hashCode());
	}

}
  • 运行结果:

  • 结果分析:

String 进行二次赋值时返回的是一个全新的字符串,内容是做到了更改,但不是那个它了。。。

StringBuffer StringBuilder 进行内容更改(二次赋值)时,返回的还是那个它。。。

  • 原因:

就像常量池一样,在方法区中存在String池,新建String时,检查String池,若无相同内容的String,会在池中创建相应内容的String后建立引用,若String池中存在相同内容的String,直接给出引用~

注意:String池 区分大小写(JAVA是区分大小写的语言~)

  • String的底层实现:
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];
    
    ......

由源码可得:String str = "ABCD"  等价于  char[ ] value = new char[ ]{'A','B','C','D'}

可以看到 String 的底层实现就是那个 value 数组,为什么不可变, value 数组都 final 了还想变 ?。。。。。。

  • 字符序列?

再悄悄告诉你们,String ,StringBuffer StringBuilder 的底层实现都是 char 数组

哈哈哈哈!!!看看这标红的三兄弟。。。哈哈哈哈。。。

看下面的源码贴图:

  • 一个有趣的小题:
public class Demo4 {
	public static void main(String[] args) {
		
		String str1[]={"ABC","abc"};
		for(int i=0;i<str1.length;i++){
			System.out.println(str1[i].toLowerCase());
			System.out.println(str1[i]);
		}
		
	}

}

问:运行结果是什么?

运行结果:

虽然:String 无论哪种创建方式,只要修改了内容就不再是原来的那个 String 了

但是:确实数组是引用类型传址过去了,但是 toLowerCase(toUpperCase 等)的执行过程是创建一个新 String 返回,并不影响 原String 本身。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值