String str1 = new String("abc");
Stirng str2 = "abc";
虽然两个语句都是返回一个String对象的引用,但是jvm对两者的处理方式是不一样的。
对于第一种,jvm会在内部维护的strings pool中放入一个"abc"对象,并在heap中创建一个String对象,然后将该heap中对象的引用返回给用户。
对于第二种,jvm首先会在内部维护的strings pool中通过String的equels方法查找是对象池中是否存放有该String对象,如果有,则返回已有的String对象给用户,而不会在heap中重新创建一个新的String对象;如果对象池中没有该String对象,jvm则创建新的String对象添加至strings pool中,将其引用返回给用户。
注意:使用第一种方法创建对象时,jvm是会主动把该对象放到strings pool里面的。
问题:对于第一种,jvm会在内部维护的strings pool中放入一个"abc"对象,并在heap中创建一个String对象,然后将该heap中对象的引用返回给用户。
堆中创建的String 对象和 字符串常量池中的abc 对象是什么关系?难道只是为了跟别的String 对象或变量 equals 时候用的吗?
------解决思路----------------------
放入字符串池是在编译期(任何字面量值的字符串都是在编译期放入字符串常量池中的).
第一句话以后池里面就已经有abc. 编译的class会记录这个池中的引用, 等到运行期new String 的时候根据这个引用找到池中的值复制一份到堆上. 把堆内存地址给str1.
所以它们只是值相同, 没其它关系
------解决思路----------------------
String s1 = "abc"; 1
String s2 = "abc"; 2
String s3 = new String("abc"); 3
java内存中有一个专门存储字符串的字符池(常量池)。当 1 执行时,字符池了新建“abc”
的字符串。s1指向它。 当 2 执行时,因为字符池里已经有“abc”字符串,所以
不会创建新的字符,将s2指向已有的“abc”。所以s1 == s2为true。s2 == "abc"为true。
当第 3 执行时,创建了两个对象。第一个s3的引用,位于栈内存,第二个new String();
位于堆内存,s3指向堆内存。
------解决思路----------------------
在第一种方式中常量池中"abc"对象会被当做普通参数传递给构造函数的.
------解决思路----------------------
正解,我记得java编程思想里有解释
------解决思路----------------------
个人理解应该是将字符串常量中的“abc”复制一份到堆内存中。
------解决思路----------------------
正解,我记得java编程思想里有解释
恩 四楼答的这些我是知道的。
我想问问s3 引用的堆中的"abc" 和 字符串常量池中已经存在的"abc" 是什么个关系?
这个问题问得好。对于你给的这个特定的具体的例子,我明确适之你,s3引用的堆中的那个“abc”(一个字符序列的空间) 与 字符串常量池中已经存在的"abc"(已化为一个字符序列),是同一个!即:(对于你这个特定的例子)s3引用的堆中的那个字符数组与 字符串常量池中已经存在的"abc"中的字符数组,是同一个!
------解决思路----------------------
内存的存放位置不同,一个堆内存,一个在常量区 一个会在垃圾处理器及时的处理 一个会保留