如题,在知乎看见一个daolao说,字符串常量池存的引用,然后自己按他的思路,对比了很多例子,确实说的过去,但是又看到javaGuide作者又说字符串常量池存的对象
那我就不明白了,比如
String str1 = new String("abc")
String str2 = "abc"
比较str1==str2 ? false
按知乎dalao的理解是,
1.首先查看字符串常量池中是否有字面量"abc"对应的引用,结果不存在,则在堆中创建字面量"abc"并将其引用放入字符串常量池中,然后再堆内存中开辟一个新空间,内容是"abc",并创建其引用放入常量池中
2.第二个式子,首先查看字符串常量池中是否有对应字面量的引用,发现是有,直接返回其引用
因为两个引用不一样。即都在常量池中(引用地址相同),但其本身不同,故false
按javaGuide作者
1.首先查看字符串常量池是否有字面量”abc“,没有,则在常量池中创建,然后因为new,故在堆内存中开辟空间,创建”abc“,然后直接返回其引用
2.第二个式子,查看常量池中是否有字面量”abc“,发现有,则直接返回其引用
也就是说,一个是引用的常量池中的字符串,一个引用的是堆中字符串,故false,那么问题来了,照这个说法引用存在哪里?
我比较支持第一种,但是又看到java8 intern相关注释又明确表示了字符串常量池存字符串本身,我tm,蒙蔽了
R大都这么讲了,我还是相信第一种吧
在堆中创建字面量"abc"并将其引用放入字符串常量池中,然后再堆内存中开辟一个新空间,内容是"abc",并创建其引用放入常量池中。这句话不觉得很乖很矛盾吗
感觉r大这次是错的
1、推荐你去看一下深入理解Java虚拟机,其实你在String str1 = new String("abc");的过程中,其实是创建了两个对象(常量池中没有的话),先会在常量池中创建这个对象,然后在堆内存中开辟一个空间(这是因为new关键字产生的),堆内存中存的是常量池中的对象,最后是把堆内存的地址给到str1。所以这个过程确实是按照JavaGuide作者所说。深入理解Java虚拟机说的是,常量池存的是字面量,引用并不是存在堆中,引用是存在Java虚拟机栈中的,所以str1实际上是存在栈中的。这里总结一下:这句代码实际上在常量池,堆,和栈中都有存。
2、第二句代码这个是在常量池中创建“abc”,然后栈中存引用,通过引用指向常量池的地址。
你的疑问是引用在哪里,引用是在栈中