String的两种创建方式+StringBuffer+StringBuilder

本文详细解析了Java中String、StringBuffer及StringBuilder的区别与联系,重点介绍了它们的内存分配、字符串拼接方式及其性能特点。

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

一:String
直接赋值和使用new的区别

String str = new String();
此时JVM

在这里插入图片描述

Demo_01_String

//直接赋值
String str1 = "hello";
String str2 = "hello";
String str3 = "world";
System.out.println("string==:"+(str1 == str2));//true:二者都指向常量池中同一对象,其地址值相同
System.out.println("string==:"+(str2 == str3));//false
System.out.println("string.equals:"+str1.equals(str2));//true
System.out.println("str1地址:"+str1.hashCode());	//99162322
System.out.println("str2地址:"+str2.hashCode()); //99162322
System.out.println("str3地址:"+str3.hashCode()); //113318802

// new String
String str4 = new String("hello");
String str5 = new String("hello");
String str6 = new String("world");
System.out.println("string==:"+(str1 == str4));//false:存放的地址不同
System.out.println("string==:"+(str4 == str5));//false:比较两个包装类的引用是否指向同一个对象,即在堆中的地址是否相同
System.out.println("string.equals:"+str1.equals(str4));//true 比较引用类型的值是否相等
System.out.println("string.equals:"+str4.equals(str5));//true
System.out.println("str4地址:"+str4.hashCode());	//99162322
System.out.println("str5地址:"+str5.hashCode());	//99162322
System.out.println("str6地址:"+str6.hashCode());	//113318802

//字符串相加
String strConst = str2 + str3;//是先加,然后在常量池找
String strNew = str5 + str6;//先开空间,再拼接
System.out.println(strConst.hashCode());
System.out.println(strNew.hashCode());
System.out.println("字符串相加后比较:"+(strConst == strNew));	//
System.out.println("字符串相加后比较:"+strConst.equals(strNew));

str4和str5对同一个对象的引用

Demo_02_StringBuffer

StringBuffer sbf1 = new StringBuffer("hello");
StringBuffer sbf2 = new StringBuffer("hello");
StringBuffer sbf3 = new StringBuffer("world");
System.out.println("stringBuffer==:"+(sbf1 == sbf2));	//false
System.out.println("stringBuffer.equals:"+sbf1.equals(sbf2));	//false
System.out.println("stringBuffer.equals:"+sbf2.append(sbf3));	//拼接

Demo_03_StringBuilder

StringBuilder sbu1 = new StringBuilder("hello");
StringBuilder sbu2 = new StringBuilder("hello");
StringBuilder sbu3 = new StringBuilder("world");
System.out.println("stringBuilder==:"+(sbu1 == sbu2));	//false
System.out.println("stringBuilder.equals:"+sbu1.equals(sbu2))	//false
System.out.println("stringBuilder.equals:"+sbu2.append(sbu3));
  1. 由于String变量实际上是对一个String对象的引用(指向常量池),所以两个通过new生成的String变量永远是不相等的(因为new生成的是两个对象,其(在堆中的)内存地址不同)。
  2. String是final类,其值是不可变的,看以下板栗,只是改变了赋值地址;
// 1. 重新赋值
String str1 = "hello";
System.out.println("str1原本地址:"+str1.hashCode());	//99162322
str1 = "java";
System.out.println("str1改变后的地址:"+str1.hashCode());	//3254818

重新赋值后str1指向新地址,但旧地址中保存的"world"依旧存在,但已经不再是str1所指向的,str1已经指向了其它地址。
所有对String类型进行改变的时候都会重新生成一个新的String对象,如果字符串的内容经常改变,而且不考虑多线程的话,建议使用StringBuilder

// 2. 字符串拼接后地址有无改变?
	    String strConst = str2 + str3;//是先加,然后在常量池找
		String strNew = str5 + str6;//先开空间,再拼接
		System.out.println("字符串拼接后的地址:"+strConst.hashCode()); //变成-1524582912
		System.out.println("字符串拼接后的地址:"+strNew.hashCode());	//变成-1524582912
		
	    System.out.println("sbf3原本地址:"+sbf3.hashCode());	//27134973
		System.out.println("sbf3拼接后:"+sbf2.append(sbf3));
		System.out.println("sbf3拼接后的地址:"+sbf3.hashCode());	//还是sbf3的地址27134973

查看源码可知String重写了equals()方法,但StringBuffer和StringBuilder没有

看JDK怎么说

StringBuffer

  1. 是线程安全的可变字符序列,可将字符串缓冲区安全地用于多个线程,可以在必要时对这些方法进行同步;
  2. 主要操作是 append 和 insert 方法;
  3. 没有重写equals方法

StringBuilder

  1. 此类提供一个与 StringBuffer 兼容的 API,但不保证同步;
  2. 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候,这样比buffer快
  3. 主要操作和buffer一样
  4. 没有重写equals方法

总结

  1. String = 操作少量的数据
  2. StringBuilder = 单线程操作字符串缓冲区 下操作大量数据;线程非安全的
  3. StringBuffer = 多线程操作字符串缓冲区 下操作大量数据;线程安全的
StringStringBuilderStringBuffer是Java中用于处理字符串的三种类。 String是不可变的,也就是说一旦创建就不能被修改。每次对String进行操作(如拼接、替换)都会生成一个新的String对象,原始的String对象则会被丢弃。这使得在频繁操作字符串的情况下,会产生大量的临时对象,造成内存浪费。因此,当字符串不需要频繁修改时,可以使用String来提高性能。 StringBuilderStringBuffer是可变的字符串类,它们可以进行修改操作而不会创建新的对象。两者的主要区别在于线程安全性和性能上的差异。 StringBuffer是线程安全的,所有的方法都使用synchronized关键字进行同步,保证了多线程环境下的安全性。然而,这也导致了性能上的损失,因为同一时间只能有一个线程访问StringBuffer对象。 StringBuilder是非线程安全的,它的方法没有使用synchronized关键字进行同步。这使得在单线程环境下,StringBuilder的性能比StringBuffer更好。因此,如果在单线程环境下进行字符串操作,建议使用StringBuilder。 如果需要将StringBufferStringBuilder对象转换为String对象,有两种方法可以实现。一种是通过调用toString()方法,将其转换为String对象。另一种是通过String的构造器String(StringBuffer buffer)来创建一个新的String对象,该构造器会将StringBuffer的内容复制到新的String对象中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [StringStringBufferStringBuilder类详解](https://blog.youkuaiyun.com/weixin_38568503/article/details/113794751)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值