字符串有两种创建方式:
String str = "abc";
String str = new String("abc");
第一种创建方式 JVM 会判断字符串常量池中是否包含该对象,如果有则返回常量池中对象的引用,如果没有则在常量池中创建一个新对象。
第二种创建方式在类加载阶段会将"abc"保存在 class 常量池中,调用 new 指令时会在堆中创建一个新的 String 对象。
问题:第一种创建方式是否等价于new String("abc").intern()
?
1
AoEiuV020CN 2022-09-29 18:57:18 +08:00 via Android
等价不可能的,最后这段明显多 new 一个没用的字符串,
至于是否相等,真的在意写个==判断一下不就知道了, 研究这种东西真的有用吗,你在搞 jvm 开发的话当我没说, |
2
Hurriance 2022-09-29 20:11:01 +08:00
创建过程是一样的,只不过 intern 函数是提供用来判断字符串对象的源对象(字符串常量池对象)
|
3
dcsuibian 2022-09-29 20:31:37 +08:00
不一样,new 了就代表新分配内存空间了。
|
4
cslive 2022-09-30 09:29:26 +08:00
不同 jdk 版本这个方法执行结果是不同的,具体看美团技术团队这篇文章。fastjson 中大量使用了 String#intern
https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html |
5
Kasumi20 2022-09-30 10:17:49 +08:00
感觉有点类似 Rust 中的 drop 函数?把临时内存删掉,指向一个公共的只读内存
|
6
BQsummer 2022-09-30 11:03:44 +08:00
@AoEiuV020CN 为什么会没用, 新手经常把 String 类型的字段做 synchronized 锁的对象, 而不用 intern, 导致锁失效.
@dcsuibian 上面美团文章里有说: "String#intern 方法时,如果存在堆中的对象,会直接保存对象的引用,而不会重新创建对象。" |
7
dcsuibian 2022-09-30 11:19:11 +08:00
@BQsummer 我是表达的是 new String("abc").intern()拆分一下应该是
String temp=new String("abc");① temp.intern();② "abc"本身就在常量池里面了,而 temp 又申请了内存,但如果直接"abc"的话,那就直接用常量池里的了。不用多此一举 |
8
AoEiuV020CN 2022-09-30 11:39:45 +08:00
@BQsummer #6 啊这,我仔细想了一下也没想到什么情况会需要锁 String ?
方法写了放在那里就肯定是有用的, 我想说的是没头没尾的花时间研究纠结这些东西没用, |
9
4kingRAS 2022-09-30 15:41:32 +08:00
为什么没用呢?很多优化的思维就是跟标准库学习的,复用常量池,反手我就用在平时的性能优化中
|
10
aguesuka 2022-09-30 16:57:12 +08:00
@AoEiuV020CN 总有人以 tricky 为荣, 没办法说服他们的
|
11
AoEiuV020CN 2022-09-30 17:04:34 +08:00
@4kingRAS #9 不研究这些你就没法优化了吗?
难道说你优化前写的代码就是 String str = new String("abc"); 像这样的? 那你确实要好好学学这些区别,我是觉得一般人靠常识就能避开这些坑,真到了需要在意这些细节的场景也会知道自己当下无法判断哪种是最优解,这时候针对性的学习一下就很合理, |
12
4kingRAS 2022-09-30 17:22:37 +08:00
@AoEiuV020CN 难怪你会被降权,不是没有理由的
|
13
4kingRAS 2022-09-30 17:24:58 +08:00
总有一些人有莫名优越感,跑别人提问帖上劝别人别研究这些无聊东西。你有聊你高效,你来回复这种无聊贴干嘛呢?找抽吗不是?
|
14
AoEiuV020CN 2022-09-30 17:46:01 +08:00
@4kingRAS #13 总有人无话可说只能人身攻击了,我最喜欢喷这种人喷到对方撒泼打滚了,
另外我被降权应该不是这类原因, |