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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 马林康 中级黑马   /  2012-6-30 19:08  /  1684 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. public class StringDemo {
  2.         public static void main(String[] args){
  3.                 String a ="ab";
  4.                 String b ="cd";
  5.                 String c ="abcd";
  6.                 String d =a+b;
  7.                 String e ="ab"+"cd";
  8.                 String f =a+"cd";
  9.                 String g ="ab"+b;
  10.                 String h =new String("abcd");
  11.                 System.out.println(c==d);//false
  12.                 System.out.println(c==e);//true
  13.                 System.out.println(c==f);//false
  14.                 System.out.println(c==g);//false
  15.                 System.out.println(c==h);//false
  16.                
  17.                
  18.         }

  19. }
复制代码
上面a+b 和"ab"+"cd" a+"cd"到底有什么区别 搞不清啊

7 个回复

倒序浏览
String类型的值是不可更改的,所以每次都需要新创建对象。而String e ="ab"+"cd";这一句并不需要新创建对象,直接指向c就可以了。所以只有c==e为true,其他都是false。
回复 使用道具 举报
a,b是变量,只包含指向字符串对象的地址,而"ab","cd"是字符串对象,是实际的字符串的值,所以a+b在没有使用其具体值时,只是包含地址的变量,没有具体值的;而"ab"+"cd"得到是一个新的字符串,具有具体值了。那么a+"cd"也就好理解了,是一个含有具体值和地址值的变量。
回复 使用道具 举报
03.                String a ="ab";缓存区中创建一个String对象,内容为"ab",

04.                String b ="cd";缓存区中创建一个String对象,内容为"cd",


05.                String c ="abcd";缓存区中创建一个String对象,内容为"abcd",


06.                String d =a+b;因为在编译的时候,是把a和b作为对象来处理的,所以没有简单的去掉"+"号,缓存区中创建一个String对象,内容为"abcd",

07.                String e ="ab"+"cd";编译器编译的时候已经把"+"号去掉了,所以它并没有再新创建对象,而是找到了缓存区里c所指向的那个内容为"abcd"的对象。
回复 使用道具 举报
首先楼主要有一个常量池的概念,这使得代码中的字符串常量只有一个拷贝

而大家都知道==是比较两个对象的内存地址是否相等
System.out.println(c==d);//false       对于String d =a+b; 实际上是在堆里重新创建了一个新的对象,而c是编译器就有的。所以他们的地址一定不同。
System.out.println(c==e);//true      这个其实没有多少好解释的,既然有了常量池这个东西,那么发现有就去拿就可以了。
System.out.println(c==f);//false         String f =a+"cd"; 这个也是同样的道理因为有了a+ 所以会在运行期再次给他分配一个堆的内存。
System.out.println(c==g);//false        道理同上。
System.out.println(c==h);//false         一般出现new这个关键字的时候会在内存中给他单独的给一块儿,所以相对于c从常量池中拿东西,肯定是不一样的。

希望对楼主的理解有帮助
回复 使用道具 举报
本帖最后由 feigecal 于 2012-6-30 20:42 编辑

因为"ab"和"cd"都是固定的值了,所以"ab"+"cd"也是固定的,它的值在编译时期就会被确定,是存在于栈内存中的字符池中,所以 String e ="ab"+"cd";中e就会在栈中找到"abcd",所以String c ="abcd";中的c和e是相等的。a+b中的a和b在运算出d的值之前,都没有被赋值,他们何时被赋值,以及被赋予什么样的值,JVM是不知道的,相当于都是个变数,因此a和b在被赋值之前,性质类似于一个变量。那么d就不能在编译期被确定,而只能在运行时被创建了,所以+号的作用是返回另外一个新建的String对象,而不是在栈中找string这个值,所以是在堆中存在的。所以String d =a+b;中的d是一个新new的对象,那么d的地址和c的地址自然不是同一个,所以为false。a+"cd"虽然有一个变量,但结果仍是不确定的,和a+b差不多,都是要在堆里新建一个对象返回的。




回复 使用道具 举报
自己玩 黑马帝 2012-6-30 20:43:39
7#
本帖最后由 自己玩 于 2012-6-30 20:52 编辑

javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,
而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。所以
String d =a+b;是在堆里重新创建了一个新的对象abcd;其他几个和这个道理一样,都有新的对象创建,所以为false
再看String e ="ab"+"cd";在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果abcd,所以“==”的结果是true
String h =new String("abcd"); 这里用到new关键字,所以创建了一个新的abde所以“==”也为false
回复 使用道具 举报
  • 你看下吧,我在下边加了必要的注释,相信你会看懂的
  • public class StringDemo {
  •         public static void main(String[] args){
  •                 String a ="ab";
  •                 String b ="cd";
  •                 String c ="abcd";
  •                 String d =a+b;
  •                 String e ="ab"+"cd";
  •                 String f =a+"cd";
  •                 String g ="ab"+b;
  •                 String h =new String("abcd");
  •                 System.out.println(c==d);//false//这个为什么会等于false呢?那我们首先来看下c这个对象String c ="abcd";是将内存中“abcd”的地址付给了C而我们再来看看D   String d =a+b;d是将a和b连个对象加起来创建了新的对象并把新对象地址给了d这个时候c和d里边的值谁然都是“abcd”但是,d是一个新的对象而c确不是,这个时候你用==比较他们的内存地址,既然对象都不是一个,那内存地址肯定不一样了所以是false。
  •                 System.out.println(c==e);//true//这个看似和上边是一样的为什么结果会不一样呢?其实你自己洗看看            String c ="abcd";这个是c      String e ="ab"+"cd";这个是e  在java中String类型如果使用+号的话,就等于是一个连接作用,起到吧 “ab”和“cd”两个字符串连接起来,而在编译器编译的时候会把+去掉,编译完以后就会成String e ="abcd";这样的会和c就一样了他们都是把“abcd”的内存地址取了出来,所以你用==号的时候,内存地址一致,所以输出 了true
    下边这些false的原因基本上和第一个是一样的,你只要仔细看看就会明白了
  •                 System.out.println(c==f);//false
  •                 System.out.println(c==g);//false
  •                 System.out.println(c==h);//false
  •         }
  • }
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马