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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘凯 金牌黑马   /  2013-2-5 22:13  /  2288 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class Test
{
public static void main(String[] args)
{
String s1 = "1";
String s2 = "1";
  System.out.println(s1==s2);//true???

  String s1 = new String("1");
  String s2 = new String("1");
  System.out.println(s1==s2);//false????
}
}
其中s1==s2比较的是对象在内存中的地址吧是?  
高不太清楚这个问题
String s1 = "1";
String s2 = "1";
s1 和 s2 究竟是指向同一个对象还是两个相同的对象 ?

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

5 个回复

倒序浏览
你可以以此为标准:有new存在,就在内存中创建了对象。
1、对于第一个
String s1 = "1";
String s2 = "1";
  System.out.println(s1==s2);//true???
当然是true了啊,因为s1和s2是在栈内存中的两个引用变量,这两个引用的值是相同的,当然是true啊
2、对于第二个
String s1 = new String("1");
  String s2 = new String("1");
  System.out.println(s1==s2);//false????
当然是false啦,因为你用new在堆内存中创建了两个对象,他们的值虽然相同,但是地址是不同的。所以是false啊。
也就是说第一个比较的引用变量,第二个比较的是两个对象。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
黄玉昆 发表于 2013-2-5 23:08
你可以以此为标准:有new存在,就在内存中创建了对象。
1、对于第一个
String s1 = "1";

记得毕老师的视频里有说过,"1"是建立了一个对象
那么说来
String s1 = "1";
String s2 = "1";
应该是建立了两个相同的对象
但s1 s2 应该是分别指向两个相同对象的
既然是两个对象 s1  s2的值应该是不同的地址值啊?
现在的问题是s1==s2 究竟是在比较连个对象的地址是否相同 还是比较这两个里边的内容??

毕老师还有讲说是 String s1 = new String("1"); 这么一句话 实际上是定义了两个对象, 他一句带过了
有些迷惑  求解释。

后来下API中String类中hashCode()方法 貌似有那么些懂点了, 不过还不是很清楚脑子里
回复 使用道具 举报
刘凯 发表于 2013-2-6 00:36
记得毕老师的视频里有说过,"1"是建立了一个对象
那么说来
String s1 = "1";

这么说吧,“==”是对“值”的比较,而“equals”是对“对象”的比较。
虽然“==”是对“值”的比较,但是你这里用new创建了两个对象,s1和s2指向的地址不同,是两个不同的引用,值,虽然相等,但是其状态时不同的。
举个例子说,两个人都叫张三,一个是北京的,一个是上海的,你能说他们是同一个人吗?
我用图例给你解释吧:


String的赋值问题1.png (3.61 KB, 下载次数: 54)

String赋值1

String赋值1

String的赋值问题2.png (11.2 KB, 下载次数: 58)

String赋值2

String赋值2
回复 使用道具 举报
本帖最后由 刘凯 于 2013-2-6 16:37 编辑
黄玉昆 发表于 2013-2-6 00:58
这么说吧,“==”是对“值”的比较,而“equals”是对“对象”的比较。
虽然“==”是对“值”的比较,但 ...


现在就是这个问题,"1" 是一个对象还是个常量? 毕老师的视频里又说过"abc"是建立了一个String对象,  但又看到别的帖子说,"abc"是一个常量。
1.如果是个常量,无可厚非,是放在常量区里,s1 s2都指向同一个,那就没错了。
2.如果是对象,那么应该是两个相同的对象,==比较的应该是 getClass().getName() + '@' + Integer.toHexString(hashCode())  这个值是否相同 , 所以s1 和 s2 主要的不同就在hashCode()返回值上, 又查了下String类的hashCode()   

结果 String类的hashCode()  覆盖了Object类中hashCode()方法

返回此字符串的哈希码。String 对象的哈希码根据以下公式计算:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希值为 0。)
所以说 s1  s2 所指向的两个对象由于都是"1"  所以其hashCode()返回值是相同的  
进而getClass().getName() + '@' + Integer.toHexString(hashCode())  是相同的,  所以 s1==s2 是true

所以第二种说法也能讲的通了

现在就是有一个新的问题  到底"1"是个常量  还是个对象   反正毕老师的视频上说是一个对象  我感觉也应该是一个对象
回复 使用道具 举报
刘凯 发表于 2013-2-6 16:34
现在就是这个问题,"1" 是一个对象还是个常量? 毕老师的视频里又说过"abc"是建立了一个String对象,  但 ...

还是那句话,你看到new,就是创建了一个对象,至于是不是你说的“1”是不是一个对象,因为String这个类型很特殊,所以这还要在以后慢慢学习中体会。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马