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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李鑫 初级黑马   /  2012-5-31 22:23  /  3408 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李鑫 于 2012-6-6 12:29 编辑
  1. public static void test() {   
  2.     String x = "hello";   
  3.     String y = "world";   
  4.     String z = new String("helloworld");   
  5.     String a = "helloworld";   
  6.     System.out.println("a == z:" + (a == z));   
  7.     System.out.println("x == hello:" + (x == "hello"));   
  8.     System.out.println("a == x+y:" + (a == (x + y)));   
  9. }  
  10. 我认为x和y相加放在常量池中与a相比较,应该返回的是true,可为什么是false呢?求指教
复制代码

评分

参与人数 1技术分 +1 收起 理由
攻城狮 + 1 赞一个!

查看全部评分

10 个回复

倒序浏览
我们从头分析下这个程序:
首先定义 String x = "hello";                              这时在常量池中(Constant Pool)有了一个x的存储结构
然后     String y = "world";                             这时,常量池又多了一个y的存储结构
到这里    String a = "helloworld";                       又多了一个a的存储结构

然后,System.out.println("a == x+y:" + (a == (x + y)));   这个的意思可以理解为:拿x+y的值与a比较是不是同一个引用,也就是比较他们在逻辑上是否相同,他们在常量池中是有不同结构的。只有当定义例如:
String a = "aaaaa"
String b = "aaaaa"
这样的,定义了相同值的常量,,在Constant Pool中才只会创建一个,所以在编译好的class文件中,我们只能找到一个对"aaaaa"的表示。但是你令两个常量相加,虽然值会与另外一个相同,但是不会覆盖的。
回复 使用道具 举报
  1. class  Demo2
  2. {
  3.         public static void test() {   
  4.     String x = "hello";   
  5.     String y = "world";   
  6.     String z = new String("helloworld");   
  7.     String a = "helloworld";   
  8.     System.out.println("a == z:" + (a == z));   
  9.     System.out.println("x == hello:" + (x == "hello"));   
  10.     System.out.println(x + y);   
  11. }  
  12. }
复制代码
你可以先用这个代码输出x+y的值,结果是 hello world。中间是有空格的,而你定义的a=helloworld中间没有空格,所以输出结果为假。
谢谢。
回复 使用道具 举报
“==”在引用数据类型中比较是的是引用变量指向堆内存中该对象的首地址,
如果首地址相同(也就是指向同一个对象)时,返回true,否则返回false.
因为String是特殊的引用类型.所以x+y这个字符串所指向的地址跟a中"helloworld"是不一样的.
回复 使用道具 举报
刘伯阳 发表于 2012-5-31 22:46
我们从头分析下这个程序:
首先定义 String x = "hello";                              这时在常量池中(C ...

回答的很好,赞一个!
回复 使用道具 举报
常量池中存放的是编译时已确定的数据,x,y这样的引用变量不在此范畴内,
x + y是在运行时创建的,和a明显不是同一数据

如果比较:a ==  "hello" + "world",则返回为true
"hello" 和"world"都是字符串常量,它们相加仍是字符常量

或者在x,y引用前加final修饰,指明x,y是常量
  final String x = "hello";
  final String y = "world";
这样,a ==  x + y;也返回true

回复 使用道具 举报
运行了下程序得到了这样的结果:
a == z:false
x == hello:true
a == x+y:false
这是因为==比较的是双方的引用变量,a与z很容易辨认是两个不同的引用变量创建了两个字符串对象,因而比较为false。x = "hello"呢是定义的字符串常量放到了常量池中x与常量"hello"比较的时候,就从常量里引用x因而比较结果是true。x+y相当与是StringBuffer.append(x).append(y),这是在创建新的实例对象,创建了新的引用因而不会与a这个字符串常量的引用相等,比较结果也就是false了。
回复 使用道具 举报
2个关键点:
1. 字符串是可以像基本类型那样使用的引用类型
2. 字符串不可变
  1. String x = "hello";
  2. String y = "world";
  3. String a = "helloworld";
  4. System.out.println("a == x+y:" + (a == (x + y)));
复制代码
以上4条语句中,共创建了4个字符串,x是一个,y是一个,a是一个,x+y又是一个。
a和x+y在内存中并不在同一个地址空间,而字符串又是引用类型且运算符==比较是否同一个。
很显然,a和x+y并不是同一个字符串。

回复 使用道具 举报
x和y相加放在常量池中与a相比较,应该返回的是true,可为什么是false呢?
  String x = "hello";   
    String y = "world";   
System.out.println("a == x+y:" + (a == (x + y)));   
是因为(x + y)涉及到变量的相加,其内部实现是先new一个StringBuilder,
然后 append(x).append(y),所以会生成新的对象.所指向的地址所以不会一样。

回复 使用道具 举报
cro 初级黑马 2012-6-1 23:27:40
10#
这个“==”比较的是引用地址是否相等,并没有比较对象啊!
回复 使用道具 举报
==比较的是内存中的地址,应该用.equals()比较
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马