黑马程序员技术交流社区

标题: 关于String的细节问题 [打印本页]

作者: Aron    时间: 2014-6-21 00:22
标题: 关于String的细节问题
本帖最后由 Aron 于 2014-6-22 15:14 编辑

大家大部分人都知道对于一个String s = new String("abc");这样一句语句实际上是创建了两个对象
我的理解是因为当new 这个对象时调用了String里面相对应的构造方法而这个构造方法里面是接受了一个String的对象,这里会创建一个对象,然后在 new String()会创建一个对象,这个新建的对象是“abc”的副本,只是值和它一样
我是想说因为String是不可变的,当使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中
所以虽然new String("abc")但是在缓冲池中还是有了一个abc
所以           String s1 = new String();
                 s1="abc";
                 String s2="abc";
                 System.out.println(s1==s2);
结果是true
而              String s1 = new String("abc");
                 String s2="abc";
                 System.out.println(s1==s2);
结果是false
我理解对不对啊?
作者: 流覽這    时间: 2014-6-21 09:29
这两段代码都应该是true; 这两字符串“abc” 地址是一样的;都是引用String 里边的字符串值;
作者: 流覽這    时间: 2014-6-21 09:30
我也不理解,往楼下有详解!
作者: z-翔    时间: 2014-6-21 11:19
本帖最后由 z-翔 于 2014-6-21 11:22 编辑

我的理解是:String s1 = new String();这句话是s1指向了new String()这个对象
然后s1="abc"是s1又指向了"abc"这个对象
所以s1==s2结果为true
而下边的s1是两个对象,s2是一个对象,所以s1和s2不可能相同,结果为false

作者: 小生    时间: 2014-6-21 12:41
我也不是很清楚,只等楼下的给详解
作者: crazystraw    时间: 2014-6-21 13:27
只知道结果,但是对于原因还是晕晕的
作者: 钟翠翠    时间: 2014-6-21 13:33
我也不理解 等着楼下的解答
作者: Aron    时间: 2014-6-21 20:44
本帖最后由 Aron 于 2014-6-21 20:48 编辑
不会java 发表于 2014-6-21 09:42
String s1 = new String("abc");
不会影响字符串池。

这个虽然是new一个但是不是要接受一个String对象的嘛  这个abc 不会存在字符串池中啊?我说的这个abc是指在新建对象是传给s1这个新建的对象的String对象
作者: Aron    时间: 2014-6-21 20:46
z-翔 发表于 2014-6-21 11:19
我的理解是:String s1 = new String();这句话是s1指向了new String()这个对象
然后s1="abc"是s1又指向了"a ...

你的意思是说我的理解是对的是不啊
就是 当new String("abc")时 字符串池中会有一个abc  因为建立这个abc这个对象的时候已近在字符串池中加入了 是不是啊
作者: 姿_`态    时间: 2014-6-21 21:39
本帖最后由 姿_`态 于 2014-6-21 22:37 编辑

class Test11
{
        public static void main(String args[])
        {
      String s1="abc";
          String s5="abc";          System.out.println(s1);
          System.out.print(s1.equals(s5));
          System.out.println(s1==s5);

          s1=new String();
          System.out.println(s1);
          System.out.println("上面是一个空格");

          String s2=new String();
          System.out.println(s2);
          System.out.println("上面是一个空格");


          String s3 = new String("bcd");
          String s4="bcd";
          System.out.println(s3==s4);
          System.out.println(s3.equals(s4));
           }
}
/*  输出结果:
truetrue
abc

上面是一个空格

上面是一个空格
false
true
*/

关于 String s1="abc"; 创建了一个对象,不过这个存在于字符串 池,s1首先去字符串 池看看有没有abc,如果有直接指向他,如果没有,自己创建一个。
对于  s1=new String();s1创建了一个对象,这个对象存在于堆内存中,原本指向字符串 池中的s1现在指向了堆,所以输出了什么都没有。对于 String s3 = new String("bcd"); 我的理解是,创建了两个对象,一个是字符串池中bcd,一个是栈中的String,但是s3指向的是栈。
对于String s4="abc"; 创建了一个对象,存在于字符串池中,s4指向字符串。

==和equals的区别是
==是指两个对象是否指向同一个内存地址

equals是指两个对象是否相同的内容。


所以s3和s4指向的不是一个内存地址,s3指向的是堆,s4指向的是字符串池,所以==返回的是false;
       s3和s4两个个对象中内容是相同的,他们的实际对象都是abc,所以是equals  返回的是true;
















欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2