老问题
String s =new String("abc");
池中到底有没有 “abc”
比如
1 String s = new String("abc");
2 String a = "abc";
结果肯定为false;
有一种答案认为 1会在 堆中创建1个对象 然后去看池 发现池中没有“abc” 然后将“abc”添加到池中
所以运行2 的时候 先去搜索池 发现池中有“abc” 所以返回地址 1的引用指向堆中的对象 2中的引用指向池中的对象
但是 网上搜资料有
原理2:
Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。(jvm会马上在heap中创建一个String对象,然后将该对象的引用返回给用户。使用这种方法创建对象时,jvm是不会主动把该对象放到strings pool里面的,除非程序调用 String的intern方法。)
//例子1
String str1 = new String("abc");
//jvm 在堆上创建一个String对象
String str2 = "abc";
//jvm 在strings pool中找不到值为“abc”的字符串,因此
//在堆上创建一个String对象,并将该对象的引用加入至strings pool中
//此时堆上有两个String对象
//例子2
String str11 = new String("abc"); //jvm 在堆上创建一个String对象
str11 = str11.intern();
//程序显式将str1放到strings pool中,intern运行过程是这样的:首先查看strings pool
//有没“abc”对象的引用,没有,则在堆中新建一个对象,然后将新对象的引用加入至
strings pool中。执行完该语句后,str1原来指向的String对象已经成为垃圾对象了,随时会被GC收集。
//此时,jvm发现strings pool中已有“abc”对象了,因为“abc”equels “abc”
//因此直接返回str1指向的对象给str2,也就是说str2和str1引用着同一个对象,
//此时,堆上的有效对象只有一个。
String str22 = "abc";
if(str11 == str22){
System.out.println("str11 == str22");
}else{
System.out.println("str11 != str22");
}
//打印结果是 str11 == str22
希望高手解答
另外 引用不叫对象 说什么生成3个 5个对象的就歇歇吧。。。
------解决方案--------------------
果然是不朽的问题
通过反编译来看看吧
public class StringTest {
public static void main(String[] args) {
new String("abc");
}
}
javac StringTest.java //编译
javap -verbose StringTest //反编译
反编译结果
D:\Test>javap -verbose StringTest
Compiled from "StringTest.java"
public class StringTest extends java.lang.Object
SourceFile: "StringTest.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #6.#15; // java/lang/Object."<init>":()V
const #2 = class #16; // java/lang/String
const #3 = String #17; // abc
const #4 = Method #2.#18; // java/lang/String."<init>":(Ljava/lang/String
;)V
const #5 = class #19; // StringTest