当前位置: 首页 > news >正文

【Java扫盲篇】String、String Buffer和String Builder的区别

你在面试时,面试官让你讲讲String String Buffer String Builder的区别,你是否能流畅的、完整的叙述出他们三者的区别?

✍先说结论

  • 相同点: 他们的底层都是由char数组实现的。
  • 不同点:
  1. String对象一旦创建,是不能修改的,如果要修改,会重新开辟空间来存储修改后的对象;而String Buffer和String Builder创建的对象是可以修改的。
  2. String Buffer是线程安全的,他几乎所有方法都被synchronization 所修饰,允许采用多线程的方式执行添加或删除字符的操作,但是效率比较低;而String Builder是单线程的。如果所有字符串在一个单线程中编辑(通常都是这样),则应该使用String Builder。这两个类的API大部分是相同的。
    总结
  • 当在程序中需要频繁的更改字符串的内容时,不要使用String(会浪费大量的空间)
  • 如果是要考虑线程下的安全问题时,使用StringBuffer
  • 否则使用String Builder

✍String类

String的三种构造方法

public static void main(String[] args) {// 使用常量串构造String s1 = "hello bit";System.out.println(s1);// 直接newString对象String s2 = new String("hello bit");System.out.println(s1);// 使用字符数组进行构造char[] array = {'h','e','l','l','o','b','i','t'};String s3 = new String(array);System.out.println(s1);
}

我们要理解String类,首先要搞清楚String的底层
通过源码可以看出
String是一个引用类型

在这里插入图片描述

我们举几个实际的例子
来更清楚的了解String的本质

请你先判断这个表达式的结果是什么
在这里插入图片描述

答案为true
我们画图来理解
在这里插入图片描述

再判断一下这个表达式的值是什么
在这里插入图片描述

结果为false
在这里插入图片描述

✍字符串的不可变性

在这里插入图片描述
在这里插入图片描述

  1. String类被final修饰,表明该类不能被继承
  2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。

✍为什么String要设置成不可变类型

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

易错点

在这里插入图片描述

  • Java中有常量优化机制,“Hello"和"World"本身就是字符串常量,所以在编译时,会直接把"Hello"和"World"合并成"HelloWorld"字符串,又因为在执行s3的时候已经在常量池中创建了"HelloWorld".
  • 当变量与字面量或变量与变量进行拼接时,会在堆中创建一个StringBuilde对象,然后使用StringBuilder的append()方法将变量与字面量或变量与变量进行拼接,最后调用toString()方法转成String对象。所以s5、s6、s7指向的都是堆内存中String对象的地址值。
public static void main(String[] args) {final String s1="Hello"; String s2="HelloWorld";String s3=s1+"World";System.out.println(s2==s3); //true
}

被final修饰表示是一个常量,所以此时s1+“World"就相当于"Hello”+“World”,结果仍然是一个常量。

有人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。
这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。

所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

以上就是本文所有内容,如果对你有帮助的话,点赞收藏支持一下吧!💞💞💞

相关文章:

  • iOS开发 - 转源码 - __weak问题解决
  • spikingjelly学习-使用单层全连接snn脉冲神经网络识别mnist数据集
  • websocket 内的操作码fin和opcode
  • 数据结构万字总结(超级详细)第二章——线性表
  • JVM虚拟机-实战篇
  • AI+云平台|全闪云底座迎战
  • 自媒体用ChatGPT批量洗稿软件V5.9环境配置/软件设置教程【汇总】
  • UE5C++学习(四)--- SaveGame类存储和加载数据
  • Sql Server小技能:row_number()函数
  • 【Vue】Vue集成Element-UI框架
  • 深圳区块链交易所app系统开发,撮合交易系统开发
  • 服务器总是宕机问题记录
  • 【WPF应用7】 基本控件-Grid 布局的详解与示例
  • 如何在Linux系统使用Docker本地部署Halo网站并实现无公网IP远程访问
  • Python读取csv文件入Oracle数据库
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 03Go 类型总结
  • 78. Subsets
  • Angular4 模板式表单用法以及验证
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS+CSS实现数字滚动
  • Python学习笔记 字符串拼接
  • Redux系列x:源码分析
  • 翻译:Hystrix - How To Use
  • 关于字符编码你应该知道的事情
  • 将 Measurements 和 Units 应用到物理学
  • 解析 Webpack中import、require、按需加载的执行过程
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 入门级的git使用指北
  • 网络应用优化——时延与带宽
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 我这样减少了26.5M Java内存!
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • #define、const、typedef的差别
  • #NOIP 2014# day.2 T2 寻找道路
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (arch)linux 转换文件编码格式
  • (BFS)hdoj2377-Bus Pass
  • (C语言)球球大作战
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (笔试题)分解质因式
  • (一)Java算法:二分查找
  • (一)u-boot-nand.bin的下载
  • (转) 深度模型优化性能 调参
  • .Net core 6.0 升8.0
  • .NET Micro Framework初体验(二)
  • .net 后台导出excel ,word
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • [C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数
  • [Codeforces] number theory (R1600) Part.11
  • [C语言]——柔性数组
  • [datastore@cyberfear.com].Elbie、[thekeyishere@cock.li].Elbie勒索病毒数据怎么处理|数据解密恢复