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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 高正新 中级黑马   /  2012-10-25 16:27  /  1471 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 水木桶 于 2012-10-26 09:35 编辑

<code>
public class StringTest {

    public static void main(String[] args) {
        String a = "b1";
        String b = "b";
        b += 1;
        System.out.println(a == b);
    }

}
</code>
这个结果为什么是false?内存里面什么情况啊?


评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1

查看全部评分

6 个回复

倒序浏览
JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即 b += 1;无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。
可以这样试下
final String b = "b" ; String bb = b + "1";
System.out.println(a == bb);

评分

参与人数 2技术分 +1 黑马币 +6 收起 理由
韩军博 + 1 很给力!
高正新 + 6 很给力!

查看全部评分

回复 使用道具 举报
本帖最后由 鲁中需 于 2012-10-25 17:13 编辑
  1. public class StringTest {

  2.      public static void main(String[] args) {
  3.          String a = "b1";
  4.          String b = "b";
  5.          b += 1;
  6.          System.out.println(b);//b1
  7.          System.out.println(a.equals(b));//true
  8.          System.out.println(a == b);//false
  9.      }
  10. }
复制代码






String b对应的内容的确是字符串“b1”,之所以为false,那就涉及到了==与equals的区别了:
如:如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
     equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:
     String a=new String("foo");
     String b=new String("foo");
     两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即ab中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true

内存结构

未命名1.jpg (56.2 KB, 下载次数: 64)

未命名1.jpg

点评

赞~!  发表于 2012-10-25 18:29
回复 使用道具 举报
范贞亮 发表于 2012-10-25 16:45
JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即 ...

大哥,为啥那个 b 用final修饰后就是真,不用final修饰就是假呢?
回复 使用道具 举报
String a = "b1";这种赋值方式首先会在JVM内存的常量池中查找是否有“b1”对象,如果有则返回该对象的引用;如果没有则创建“b1”对象,放到常量池中,然后返回新创建对象的引用。基于此,String a和 String b分别值是“b1与b”。所以,两个判断语句肯定是false!
回复 使用道具 举报
  1. String a = "b1";
  2.         String b = "b";
  3.         b += 1;
  4.         System.out.println(a==b);//false
  5.         System.out.println(a .equals(b));//true
复制代码
在内存中,a的引用是一个对象,b的引用是另一个对象。
就算通过连接字符串相等,在堆内存中是另一个对象。
而String覆盖了object的equals()方法,用equals就相等了
回复 使用道具 举报
ssx0101 中级黑马 2012-10-25 18:03:40
7#

  1. <P>public static void main(String[] args) {
  2.   // TODO Auto-generated method stub
  3.   
  4.           String a = "b1";//在堆中开辟地址(地址1)存放“b1”,把地址1的值存在栈中某个位置1,a指向该位置
  5.           String b = "b";//在堆中开辟地址(地址2)存放“b”,把地址2的值存在栈中某个位置2,b指向该位置
  6.           b += 1;//地址二的值”b“改为”b1“
  7.           System.out.println(a == b);//判断a和b是否指向栈中同一位置由于位置1和位置2是不同的,所以结果为false
  8.           System.out.println(a.equals(b));//判断地址1里存放的值”b1“和地址2里存放的值”b1“是否相同,结果为true
  9.       }</P>
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马