黑马程序员技术交流社区

标题: String类中两个对象是否相等的问题 [打印本页]

作者: 郭冰川    时间: 2012-12-29 13:07
标题: String类中两个对象是否相等的问题
本帖最后由 郭冰川 于 2012-12-29 19:32 编辑

class StringDemo
{
        public static void main(String[] args)
        {
                String s1 = "abc";
                String s2 = new String("abc");
                String s3 = "abc";
               
                System.out.println(s1==s2);
                System.out.println(s1==s3);

        }
}
输出结果:
false
true
毕老师说s1=s3是因为“abc”字符串是在常量池中,所以s3不开辟空间直接指向这个地址,那s2的“abc”不是在常量池中吗?为什么不相等呢?
作者: 黑马斯巴达    时间: 2012-12-29 13:29
s2是通过new来创建的对象,和s1不是同一个对象自然不相等,也就是说指向的对象不同!
作者: 郭冰川    时间: 2012-12-29 13:40
谢军 发表于 2012-12-29 13:29
s2是通过new来创建的对象,和s1不是同一个对象自然不相等,也就是说指向的对象不同! ...

我知道new肯定是新创建了个对象,那么s2的“abc”在哪呢,是在常量池吗,如果在常量池为什么跟s1,s3的地址值不一样,如果不做常量池那么在哪呢?
作者: zjqlovelyy    时间: 2012-12-29 13:42
下面是String文档的说明,而==比较的是引用,equals比较的才是内容

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:

         String str = "abc";
     

is equivalent to:

         char data[] = {'a', 'b', 'c'};
         String str = new String(data);
  1. /*异常*/

  2. class  StringDemo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 byte []ch = {'a','b','c'};
  7.                 String s1 = "abc";
  8.                 String s2 = new String(ch);
  9.                 String s3 = "abc";
  10.                System.out.println(s1==s2);
  11.                            System.out.println(s1==s3);
  12.                                 System.out.println(s1.equals(s2));
  13.             

  14.         }
  15. }
复制代码

未命名.jpg (6.8 KB, 下载次数: 41)

未命名.jpg

作者: 郭冰川    时间: 2012-12-29 13:47
zjqlovelyy 发表于 2012-12-29 13:42
下面是String文档的说明,而==比较的是引用,equals比较的才是内容

Strings are constant; their values  ...

我知道==比较的是引用,只是不知道为什么s1和s3的地址值一样,和s2的却不一样。
作者: 黑马斯巴达    时间: 2012-12-29 13:51
郭冰川 发表于 2012-12-29 13:40
我知道new肯定是新创建了个对象,那么s2的“abc”在哪呢,是在常量池吗,如果在常量池为什么跟s1,s3的地 ...

应该不在常量池的。。具体在哪我也不知道。。这个不是重点,只要弄清他们的关系就好
作者: 郭冰川    时间: 2012-12-29 13:58
谢军 发表于 2012-12-29 13:51
应该不在常量池的。。具体在哪我也不知道。。这个不是重点,只要弄清他们的关系就好 ...

嗯,不抠那么细了
作者: 李敬卫    时间: 2012-12-29 14:20
s1和s3的abc在字符串常量池中,当s3对象建立的时候,他首先会在常量池中寻找是否有相同的字符串,如果有就不会在开辟新空间去存放s3指向的字符串,而是直接s3指向s1对象所在的地址,所以s1==s3为true。而s2指向了new出来的对象地址,一般new出来的对象存在堆内存中,内存指向不同,也就是说引用不同,那s1==s2肯定也就为false了。个人理解,请高手指正…
作者: 郝福明    时间: 2012-12-29 18:07
s1创建或者不创建一个新对象,new是创建一个对象,s1是直接放入内存池中,s3会先查找内存池,如果有就不创建了,没有就创建,所以s1==s3
作者: 王玮    时间: 2012-12-29 18:56
第一:对于 String s2 = new String("abc") ,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址
第二:对于 String   s1  =   "abc ";先定义一个名为s1的对String类的对象引用变量:String   s1;,然后,在栈中(字符串常量池)查找有没有存放值为 "abc "的地址,如果没有,则开辟一个存放字面值为 "abc "的地址,接着创建一个新的String类的对象s,并将s 的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象s。如果已经有了值为 "abc "的地址,则查找对象s,并返回s的地址。最后,将s1指向对象s的地址。

作者: 郭冰川    时间: 2012-12-29 19:27
王玮 发表于 2012-12-29 18:56
第一:对于 String s2 = new String("abc") ,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是 ...

多谢解答




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