日期:2014-05-20  浏览次数:20643 次

String 使用new 方法时池中到底有没有生成对象
老问题 
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