求大神指点字符串相加问题!!

掌心一点微笑 2018-09-10 11:32:25
String str2 = new String("str")+new String("01");
str2.intern();
String str1 = "str01";
System.out.println(str2==str1);
返回 true ,如果将第一行换成String str2 = new String("str01");返回 false,为什么?
...全文
251 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
掌心一点微笑 2018-09-11
  • 打赏
  • 举报
回复
引用 9 楼 qq_35175535 的回复:
1.String s = new String("11ab");
首先,肯定会在堆中创建一个新的对象,在常量池中查找是否有值为"11ab"的字符串对象,如果有,则将此对象的value属性赋给新创建的字符串对象,如果没有,先新建一个字符串对象放入常量池,再将它的value属性赋给s。内存中必然会存在s和常量池中的对象,他两的value值都为"11ab",但不是同一个对象。
2.String s = new String("11") + new String("ab");
参照1,常量池会有value属性值为"11"和"ab"的两个对象,相加,在堆中创建s,将"11"和"ab"这两个常量池对象的value copy给s的value,但此时没有在常量池中加入"11ab",只是会存在"11"和"ab"。
3.intern:和楼上的解释一样
看看你的代码:
1.
String str2 = new String("str")+new String("01"); //常量池:"str"和"01"
str2.intern(); //常量池:"str","01"和"str01"(这个对象就是str2指向的对象)
String str1 = "str01"; //判断常量池发现有"str01",直接将其赋给str1,即将str2指向的对象赋给了str1
System.out.println(str2==str1);
2.
String str2 = new String("str01"); //常量池:"str01"(但是str2指向的不是这个对象)
str2.intern(); //常量池:"str01"
String str1 = "str01"; //判断常量池有,将常量池的"str01"赋给str1
System.out.println(str2==str1);
完全搞懂了,String str2 = new String("str01"); 这一步,常量池里面已经有 str01了,str2.intern(); 这一步相当于啥都没做,而str1指向常量池里面的对象,而str2指向堆中的对象,所以 false,谢谢大佬指点.
wildyy 2018-09-11
  • 打赏
  • 举报
回复
1.String s = new String("11ab");
首先,肯定会在堆中创建一个新的对象,在常量池中查找是否有值为"11ab"的字符串对象,如果有,则将此对象的value属性赋给新创建的字符串对象,如果没有,先新建一个字符串对象放入常量池,再将它的value属性赋给s。内存中必然会存在s和常量池中的对象,他两的value值都为"11ab",但不是同一个对象。
2.String s = new String("11") + new String("ab");
参照1,常量池会有value属性值为"11"和"ab"的两个对象,相加,在堆中创建s,将"11"和"ab"这两个常量池对象的value copy给s的value,但此时没有在常量池中加入"11ab",只是会存在"11"和"ab"。
3.intern:和楼上的解释一样
看看你的代码:
1.
String str2 = new String("str")+new String("01"); //常量池:"str"和"01"
str2.intern(); //常量池:"str","01"和"str01"(这个对象就是str2指向的对象)
String str1 = "str01"; //判断常量池发现有"str01",直接将其赋给str1,即将str2指向的对象赋给了str1
System.out.println(str2==str1);
2.
String str2 = new String("str01"); //常量池:"str01"(但是str2指向的不是这个对象)
str2.intern(); //常量池:"str01"
String str1 = "str01"; //判断常量池有,将常量池的"str01"赋给str1
System.out.println(str2==str1);
verejava 2018-09-11
  • 打赏
  • 举报
回复
str1.intern 将它的地址指向字符串池

JVM 虚拟机 之 内存分配代码图解 字符串

http://www.verejava.com/?id=17433712313614
Code_Noting 2018-09-10
  • 打赏
  • 举报
回复
可以参考一下https://droidyue.com/blog/2014/12/21/string-literal-pool-in-java/
「已注销」 2018-09-10
  • 打赏
  • 举报
回复
intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。。否则,在常量池中加入该对象,然后 返回引用。
str2.intern()调用后常量池中就存在“str01”了,你再声明一个String str1 = "str01",此时str1的地址就指向常量池中的那个。。
此时str2 == str1 值为true
但是第一行用new的话,会在堆中产生对象,再返回引用。。此时声明str1才会在常量池产生"str01",两个地址不同,此时此时str2 == str1 值为false
杨菜鸟 2018-09-10
  • 打赏
  • 举报
回复



地址是不一样的,所以是false
杨菜鸟 2018-09-10
  • 打赏
  • 举报
回复
应该只有在str1.intern后,才能将它的地址指向池里面的str01,不然地址都不一样导致false。可以看下jdk
掌心一点微笑 2018-09-10
  • 打赏
  • 举报
回复
引用 1 楼 ilovelizehui 的回复:
intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。。否则,在常量池中加入该对象,然后 返回引用。
str2.intern()调用后常量池中就存在“str01”了,你再声明一个String str1 = "str01",此时str1的地址就指向常量池中的那个。。
此时str2 == str1 值为true
但是第一行用new的话,会在堆中产生对象,再返回引用。。此时声明str1才会在常量池产生"str01",两个地址不同,此时此时str2 == str1 值为false
:我觉得 不管第一行怎么new,在调用第二行str2.intern()后,常量池中就存在“str01”,然后 再声明String str1 = "str01" 都是指向常量池中的那个了,返回结果 应该是 一致的啊,求大神 指点迷津.谢谢.
掌心一点微笑 2018-09-10
  • 打赏
  • 举报
回复
引用 1 楼 ilovelizehui 的回复:
intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。。否则,在常量池中加入该对象,然后 返回引用。
str2.intern()调用后常量池中就存在“str01”了,你再声明一个String str1 = "str01",此时str1的地址就指向常量池中的那个。。
此时str2 == str1 值为true
但是第一行用new的话,会在堆中产生对象,再返回引用。。此时声明str1才会在常量池产生"str01",两个地址不同,此时此时str2 == str1 值为false
如果第一行用 new String("str")+new String("01"),然后str2.intern(); 此时 常量池中就存在“str01”了这个 我懂,但是 第一行new String("str01")之后,会在堆中产生对象,返回引用 我也懂,但是 第二行 也同样调用了str2.intern()方法,这个 难道不会在常量池生成 str01吗?

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧