黑马程序员技术交流社区

标题: String对象的疑惑 [打印本页]

作者: 黑马刘杰    时间: 2013-2-23 10:50
标题: String对象的疑惑
本帖最后由 黑马刘杰 于 2013-2-23 12:49 编辑
  1. public static void foo(){
  2.                 String str=new String("hello");
  3.                 System.out.println(str=="hello");//这里是false
  4.                 System.out.println(str.equals("hello"));//这里是true
  5.                
  6.                 String str2="hi";//str2不是对象吗?
  7.                 System.out.println(str2=="hi");//这里是true
  8.                 System.out.println(str2.equals("hi"));//这里是true
  9.                
  10.         }
复制代码
我现在有点晕了,String str=new String("hello");这里的str是对象,但是String str2="hi";这里的str2却不是对象。这是为什么啊?

作者: 逍林游    时间: 2013-2-23 10:55
String是一个特殊的对象,
String str2="hi"这句会在栈内存的常量池中存储“hi” ,然后s1引用该数据,
String str=new String("hello");在堆内存中分配String对象“hello”,然后s2引用该堆中的对象。
str2==str 这句比较的内存首地址,根据以上分析s1、s2的内存地址明显不同,所以s1==s2返回false。


作者: 陈圳    时间: 2013-2-23 11:01
equals
public boolean equals(Object anObject)将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。

覆盖:
类 Object 中的 equals
参数:
anObject - 与此 String 进行比较的对象。
返回:
如果给定对象表示的 String 与此 String 相等,则返回 true;否则返回 false。
你可以多查看API文档,这个equals比较是的对象的值,
而==比较的是首地址
String str2创建并赋值了,就是一个对象,只不过你对这俩个方法间的区别误解了.
作者: 王钊    时间: 2013-2-23 11:10
来个详细点的:
首先,String s = “aaa”;(采用字面值方式赋值)
1) 查找String Pool中是否存在“aaa”这个对象,如果不存在,则在String Pool中创建一个“aaa”对象,然后将String Pool中的这个“aaa”对象的地址返回来,赋给引用变量s,这样s会指向String Pool中的这个“aaa”字符串对象
2) 如果存在,则不创建任何对象,直接将String Pool中的这个“aaa”对象地址返回来,赋给s引用。
其次,String s = new String(“aaa”);
1) 首先在String Pool中查找有没有“aaa”这个字符串对象,如果有,则不在String Pool中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在String Pool中创建一个“aaa“对象,然后再在堆中(heap)创建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个”aaa“对象

所以,你这里String str="hello"返回的是字符串池中的对象,str=="hello",必然返回true
而,String str=new String("hello");返回的是堆中的对象,str=="hello"和池中的对象必然不是同一个。
而String重写equal方法后,对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致,可以放心使用。
作者: 唐长智    时间: 2013-2-23 11:14
str=="hello"的结果为false是因为new String 时把hello存到了堆内存中,所以地址值不相等。
str2 == "hi"的结果为true是因为"hi"存在常量池中
栈中创建一个对String类的对象引用变量str2,然后通过符号引用去字符串常量池 里找有没有"hi",如果没有,则将"hi"存放进字符串常量池 ,并令str指向"hi",如果已经有"hi" 则直接令str指向"hi"。
String 类覆写了Object的equals方法,只要值相同,equals就相同。
作者: 杨玲    时间: 2013-2-23 11:19
  1. //我一段一段的解释下吧。
  2. public static void foo(){
  3. //下面这句,是用new的,也就是说分配了一个新地址
  4.                 String str=new String("hello");
  5. //这里的==比较的是地址的值,也就是哈希值,"hello"是一个常量对象,str是一个new出来的对象,地址不一样,返回false可以理解吧               System.out.println(str=="hello");//这里是false

  6. //这一句没什么可解释的吧,用equals比较,在String类中的equals比较的是字符串。所以true;               System.out.println(str.equals("hello"));//这里是true

  7. //这一句,是让str2指向一个常量对象"hi"的地址,其实它就是这个"hi"的引用               
  8.                 String str2="hi";//str2不是对象吗?
  9.   
  10. //这一句把"hi"对象的引用的地址和它自己的地址比较,还能返回false吗?呵呵。              System.out.println(str2=="hi");//这里是true
  11.                 System.out.println(str2.equals("hi"));//这里是true
  12.                
  13.         }
复制代码

作者: 徐升2013    时间: 2013-2-23 11:58
本帖最后由 起航 于 2013-2-23 12:03 编辑

String str2="hi";//str2不是对象吗?对象怎么建立 要NEW啊  你也没NEW啊  直接赋值了 等于是个常量了 而不是对象


我回答的好像不对{:soso_e136:},不过没NEW应该是没对象的吧  这样理解应该没错
作者: 黑马刘杰    时间: 2013-2-23 12:42
逍林游 发表于 2013-2-23 10:55
String是一个特殊的对象,
String str2="hi"这句会在栈内存的常量池中存储“hi” ,然后s1引用该数据,
St ...

谢谢啦   
作者: 黑马刘杰    时间: 2013-2-23 12:42
王钊 发表于 2013-2-23 11:10
来个详细点的:
首先,String s = “aaa”;(采用字面值方式赋值)
1) 查找String Pool中是否存在“aaa”这 ...

这次我彻底明白了,谢谢啦
作者: 冯超    时间: 2013-2-23 16:07
顶一个···




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