网站首页 > 文章精选 正文
“+” 是怎么连接字符串的?(JDK1.7及以上)
总结:
使用 “+” 连接字符串时,实际上是使用临时创建的StringBuilder对象来辅助完成的。
对于编译时常量,在编译后直接计算出字符串的值,而不会在运行时创建临时的StringBuilder对象来完成字符串连接。
在循环中对String对象进行连接,应该直接使用StringBuilder代替 “+”,这样可以提高性能。
注意: 当使用运算符 “+” 连接字符串时,如果两个操作数都是编译时常量,则在编译时期就会计算该字符串的值,而不会在运行时创建StringBuilder对象。
final String s = "abc";
String x = "abc" + "def"; // 两个操作数都是常量,运行时不会创建StringBuilder对象
String y = s + "def"; // s和"def"都是编译时常量,不会创建StringBuilder对象,实际上x和y指向同一个对象,即"abcdef"
String z = y + "abc"; // y是变量,则在运行时会创建StringBuilder对象
不可修改的String对象
<1> 问:String对象一经创建,不能修改,为什么?
因为String类是final类型的,无法继承该类。
其所有的成员变量都是private的,并且没有提供修改私有成员变量的公有(public)方法
对String对象的操作都没有修改当前对象,而是新创建一个对象
<2> 问:把String对象设计成不可修改有什么好处吗?
最大好处就是可以实现资源共享,多线程操作时,具有线程安全性。
总结三点:
- String类是final类型的,其对象一旦创建,不可修改。
- String类那些看似修改字符序列的方法实际上都是返回新创建的String对象,而不是修改自身对象。
- String对象不可改变,因此具有线程安全性,可自由实现共享。
String类的内部实现
在String类内部,使用一个字符数组char[]来维护字符序列。
private final char value[];
问:String的最大长度是多少?
String的最大长度也就是字符数组char[]的最大长度,理论上为int类型的最大值,即2147483647,实际上,一般可获取的最大值小于理论最大值。
申请一个int最大值长度字符数组:
char c = new char[Integer.MAX_VALUE]; // 报错
报错:一个char类型占用2字节,Integer.MAX_VALUE个char类型接近于4GB大小,申请这么大一块连续内存空间,导致内存溢出。
//加入Java开发交流君样:756584822一起吹水聊天
分析:Java中的对象是分配在堆上的,默认的堆空间的最大值是256MB,在理想的情况下,只要我们将最大Java堆设置的足够大,就可以申请到最大的字符长度,即Integer.MAX_VALUE。
java -Xmx1G
com.fan.fragmentlearning.str.StringDemoMain – 设置Main方法最大Java堆
String常量池
<1> 什么是String常量池?
String常量池是String类内部私有的,能够自动将String字面常量加入其中。
起初,常量池是空的,当程序中出现String字面常量时,会在常量池中搜索是否存在该String对象,即使用String类的equals方法来判断,如果不存在,就将这个字面常量加入常量池中,并返回该对象;否则直接返回常量池中的对象。
<2> String字面常量和String常量表达式都会加入常量池中。
<3> 满足什么条件才算是String常量表达式呢?
即就是在编译的时候就可以确定其值的String类型表达式。编译器的原则是:能在编译期间计算的,就不会留到运行时再去计算。
第一种: 表达式全部由String字面常量拼接
String s = "a" + "b" + "c";
第二种: 表达式由String字面常量,基本类型字面常量,final修饰的String引用,final修饰的基本数据类型任意组合组成。
String s = "a" + 5; // String常量表达式
final String str = "a";
String s = "bc" + str; // String常量表达式
final int num = 5;
String s = "a" + num; // String常量表达式
String s = str + num; // String常量表达式
<4> intern方法 - 拘留字符串
如果需要将某个String对象加入常量池中,就可以调用intern方法来完成,这个操作也称作拘留字符串。
系统自动将String字面常量与String常量表达式的字符串值加入常量池中,也是通过调用intern方法来实现的。
要点总结:
String类维护一块特殊的区域,称为常量池。因为String对象是不可改变的,因此没有必要创建两个相同的String对象。只需将String对象加入常量池,在需要的时候取出,这样即可实现String对象的共享。
在程序中出现String编译时常量(String字面常量与String常量表达式),会自动调用intern方法,如果常量池中含有相等的String对象(使用String类的equals方法来判断),则直接返回常量池中的对象;否则将对象加入常量池中并返回该对象。
对于运行时创建的String对象(非String编译时常量),会分配到堆中,系统不会自动调用intern方法拘留该对象,不过我们依然可以自行调用该对象的intern方法对该对象进行拘留。
写到最后
最新2021整理收集的一些高频面试题(都整理成文档),有很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,也有详细的学习规划图,面试题整理等,需要获取这些内容的朋友请转发+私信【02】就可以免费获得领取方法!
猜你喜欢
- 2025-05-03 2021年,运维工程师笔试真题(二)(附带答案)
- 2025-05-03 600+ 道 Java面试题及答案整理(建议收藏)
- 2025-05-03 2021年阿里最新软件测试面试题:Web 测试+接口测试+App 测试
- 2025-05-03 「2021最新版」RabbitMQ面试题总结,每道题都很经典
- 2025-05-03 2021年7月初,深圳TPlink图像算法工程师面试题分享
- 2025-05-03 从12K到60K,这2021Java研发必问高级面试题,过关斩将拿offer
- 2025-05-03 字节跳动的25个软件测试经典面试题,你招架得住吗?
- 2025-05-03 蚂蚁金服软件测试工程师一面面试题(附答案)建议收藏
- 2025-05-03 GitHub2021年度前100的Java面试真题&高频知识点汇总
- 2025-05-03 字节跳动大佬最新整理的各方面面试题,PDF开放下载
- 05-05MyBatis的三种分页方式,你学废了吗?
- 05-05如何写一个简单的分页(最简单的分页)
- 05-05详解如何使用Spring Data JPA进行数据的分页与排序
- 05-05手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-05前端分页机制的具体实现(分页前端需要做什么)
- 05-05一个后勾腿动作,有效疏通血管,改善下肢发麻,促进全身燃脂
- 05-05大型调相机起动及并网研究(什么是调相机,与发电机区别)
- 05-05你们都是托:动态对比度其实是骗你的
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)