A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郭冰川 中级黑马   /  2012-12-29 13:07  /  2289 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郭冰川 于 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”不是在常量池中吗?为什么不相等呢?

评分

参与人数 2技术分 +1 黑马币 +1 收起 理由
张会文 + 1
刘芮铭 + 1

查看全部评分

10 个回复

倒序浏览
s2是通过new来创建的对象,和s1不是同一个对象自然不相等,也就是说指向的对象不同!

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
谢军 发表于 2012-12-29 13:29
s2是通过new来创建的对象,和s1不是同一个对象自然不相等,也就是说指向的对象不同! ...

我知道new肯定是新创建了个对象,那么s2的“abc”在哪呢,是在常量池吗,如果在常量池为什么跟s1,s3的地址值不一样,如果不做常量池那么在哪呢?
回复 使用道具 举报
下面是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, 下载次数: 44)

未命名.jpg

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
zjqlovelyy 发表于 2012-12-29 13:42
下面是String文档的说明,而==比较的是引用,equals比较的才是内容

Strings are constant; their values  ...

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

应该不在常量池的。。具体在哪我也不知道。。这个不是重点,只要弄清他们的关系就好
回复 使用道具 举报
谢军 发表于 2012-12-29 13:51
应该不在常量池的。。具体在哪我也不知道。。这个不是重点,只要弄清他们的关系就好 ...

嗯,不抠那么细了
回复 使用道具 举报
李敬卫 来自手机 中级黑马 2012-12-29 14:20:15
8#
s1和s3的abc在字符串常量池中,当s3对象建立的时候,他首先会在常量池中寻找是否有相同的字符串,如果有就不会在开辟新空间去存放s3指向的字符串,而是直接s3指向s1对象所在的地址,所以s1==s3为true。而s2指向了new出来的对象地址,一般new出来的对象存在堆内存中,内存指向不同,也就是说引用不同,那s1==s2肯定也就为false了。个人理解,请高手指正…

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
s1创建或者不创建一个新对象,new是创建一个对象,s1是直接放入内存池中,s3会先查找内存池,如果有就不创建了,没有就创建,所以s1==s3
回复 使用道具 举报
王玮 中级黑马 2012-12-29 18:56:03
10#
第一:对于 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 18:56
第一:对于 String s2 = new String("abc") ,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是 ...

多谢解答
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马