String str="aaa";
String str=new String("aaa");到底有什么区别?
为什么有人说  String str=new String("aaa"); 这个产生了两个对象??
有谁能够证明  前者分配的内存在栈上??而第二个在堆上???
能证明这个,小弟佩服死你!!!!

解决方案 »

  1.   

    "aaa" 是一个字符串常量,它应该放在静态存储区,和 static, final变量放在一块而new String("aaa") 创建了一个和字符串"aaa"内容一样的字符串,不过这个字符创放在堆上的。
      

  2.   

    String str=new String("aaa"); 
    在这条语句中的确产生了两个字符串,第一个字符串是字符串常量"aaa",第二个字符串是new String语句产生的字符串,它的内容和"aaa"一样。给你一段程序,就可以看出他们的区别
    String s1 = "aaa";
    String s2 = "aaa";
    String s3 = new String("aaa");
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);
    System.out.println(s1.equals(s3));如果你能把最后的结果想通,那么也就理解了"aaa" 和 new String("aaa")的区别了。
      

  3.   

    String s1 = "aaa";
    String s2 = "aaa";
    String s3 = new String("aaa").intern();
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);
    System.out.println(s1.equals(s3));
    看看这段程序和楼上的结果有什么区别?呵呵
      

  4.   

    String str="aaa";//直接使用常量 "aaa"的地址是固定的
    String str=new String("aaa");//使用对象 又创建了一个与"aaa"相同内容的字符串,但与常量"aaa"不在同一个地方String s1 = "aaa";
    String s2 = "aaa";
    String s3 = new String("aaa");
    System.out.println(s1 == s2);//true 同样使用的是常量,地址相同
    System.out.println(s1 == s3);//false 使用常量与使用对象(new出来的)是不同的
    System.out.println(s1.equals(s3));//true  内容相同,都是"aaa"
      

  5.   

    是的,第二个还产生了一个指向string 的语柄对象
      

  6.   

    作了一个简单实验,希望对大家有帮助。
    JDK 版本 1.4.2 (因JDK1.5编译有问题,故使用1.4)。1、反编译java.lang.String类
    2、修改value成员和count成员为public。(原为private)
    3、编译java\lang\String.java
    4、将编译好的类替换jdk1.4下的jre下的lib下的rt.jar中String类
    5、用新的jre环境编译下面的t.java。
    6、运行类t,得到结果//t.java
    public class t
    {
    public static void main(String arg[])
    {
    String s = "abcd";
    String t = new String(s);
    t.value[0]='A';
    s.count = 3;
    System.out.println(s);
    System.out.println(t);
    System.out.println(s.value.length);
    System.out.println(t.value.length);
    System.out.println(s.length());
    System.out.println(t.length());
    }
    }
    //运行结果如下
    Abc
    Abcd
    4
    4
    3
    4结论1:s和t确实是两个不同的对象
    结论2:s和t共享存储区域
    结论3:s和t分别对存储区域(char数组)进行管理(包括计数)未得出的结论1:s和t,谁在堆谁在栈,是系统内部概念,不知道怎么判定
    未得出的结论2:s和t在某些情况下并不共享存储,当s中有用不着的空间时,什么时候这样?
      

  7.   

    楼上的,
    你的结论1 的表述有问题, 因为 s和t不是对象,他们在Java中应该称为引用变量(conference variable),引用变量的作用是指向对象, 所以 s == t 是用来判断 s 和 t的值是不是一样,当返回值为true的时候,表示两个变量的值相等,也即表示他们都指向了同一个对象,反之,则表示他们指向了两个不同的对象。所以你的结论1应该改为: "abcd" 和 new String(s) 是两个不同的对象。其次,因为你结论1有错,所以后面的结论都有错。呵呵。
      

  8.   

    除了上面的小错误之外我认为aico(aico)说的还是很有道理。我觉得在讨论这个问题的时候,应该先看String的特点,String类是一个不可变类,也就是产生一个String对象后,这个String对象的内容是固定的不会发生任何变化。也许是这个原因,基于性能的考虑,String的设计者采用了类似于享元模式的设计方案,也就是具有相同内容的不同String对象,实际上都是指向同一块内存。但是要注意,他们仅仅共享了一段内存(这样做的原因是因为他们的内容是不可变化的),而不表示具有相同内容的对象是同一个对象。那么对于 "aaa", 所有使用了 String x = "aaa" 的引用变量x 指向的都是同一个String对象, 这些变量之间使用操作符 == 产生的结果永远是true, 而对于 new String("aaa"),所有使用了 String x = new String("aaa")的引用变量指向的都是不同的String对象,只是这些对象之间的内容都是相同的。
      

  9.   

    呵呵
    小弟先谢过各位。
    看了看 API ,下面是该构造方法的说明:
            String(String original) :
            Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.        新的string对象是 引数 original 的拷贝,所以说是两个对象。
            至于怎么证明在stack,或是heap,留作大家的思考。想出来的记得告诉我哦。
            qq:81954716
      

  10.   

    String s1= "xxx"是一个字符串常量,而String s2 = new String("xxx") 创建一个对象。System.out.println(s1 == s2);// return false 
    System.out.println(s1.equals(s2));//return true  
    由于地址不同故返回flase,可他们的内容相等都是'xxx'故返回true。