欢迎光临散文网 会员登陆 & 注册

Java面试 | 代码中创建了多少个字符串?换个思路解答

2023-07-21 23:05 作者:空挡滑行brz  | 我要投稿

关于String对象创建的问题经常出现在Java的技术面试中,网上关于这个的原理解析已经很多了,这篇文章提供一个用idea来验证的方法,不需要记住复杂的原理和源码,好记好操作。”

基本原理

JVM会用一个字符串常量池来存储字符串,这个一般开发人员都知道了,原因就是String使用的太频繁了,重用肯定比创建新对象效率来的高。当然能够用常量池的基础是String一个不可变对象,一旦创建完成,就不可修改了。Java中创建String对象的方法有好几种,下面我们用idea来验证一下不同的写法到底会创建几个对象。

开始之前,先在idea中安装一个jclasslib插件,后面会用到。这个插件可以可视化展示class文件内容。


安装idea插件

字符串对象创建

1. 代码中直接写字符串,比如String str = "abc"; 

这种方式。在idea中写一个测试方法,并且加上断点。Debug启动后,在Debug的Memory窗口就可以看到当前堆中的对象统计,Diff是指每次重新刷新后对象的数量变化。当前第一次进断点,所以Diff都是0。

创建对象前

点下一步,就可以看到,堆中新创建了1个String对象。那怎么确认这个对象是否在堆的常量池中的呢?可以在下面再加一行:

定义str2未创建对象

可以看到String str2 = "abc";执行完后,并没有创建新的String对象。所以第一行创建的String是在常量池中。


2. 使用字符串创建新字符串,如String str = new String("abc");

new创建字符串

可以发现新创建了2个String对象。一个肯定是常量池的,另外一个就是当使用new String来创建字符串的时候,堆里还会有一个普通String对象。


3. 使用字符数组创建字符串, 如String str = new String(char[]);

使用char[]创建字符串

同样只创建了一个String,继续验证是否放入常量池:

重新定义字符串

相对于第一行有2个对象创建,说明str2新创建了对象并放入了常量池。得出结论是使用字符数组创建String,不会放入常量池。


4.  多字符串连接,如String str = str0 + str1 + str2;

连接后创建新对象

字符串连接后,新创建了一个对象。继续验证一下是否在常量池:

连接后的字符串不在常量池

又新创建了一个String对象,说明字符串连接后也不会放入常量池。原因是什么呢?可以从编译出的class文件找到答案。

idea的target目录中找到编译出的class文件,点击“View->Show Bytecode With JclassLib”,如下图:

字符串连接字节码

可以看到编译后的字符串连接其实使用StringBuilder实现的。那找到StringBuilder源代码的toString()方法,发现最终使用的是new String(char[])这个构造函数。所以最终的字符串不会进入常量池。


总结

String原理是面试中经常问道的问题,这篇文章用最简单的方式验证,是否好记很多呢?😄

Java面试 | 代码中创建了多少个字符串?换个思路解答的评论 (共 条)

分享到微博请遵守国家法律