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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 悠然丶 中级黑马   /  2014-4-20 20:05  /  1760 人查看  /  10 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 悠然丶 于 2014-4-21 13:12 编辑

  String str1 = "a";
                String str2 = str1 + "bc";
                System.out.println(str2 == "abc");     //这里是false        



final String str3 = "a";
                String str4 = str3 + "bc";
                System.out.println(str4 == "abc");  //被final修饰过之后就是true了  为什么?

10 个回复

倒序浏览
字符串本身是常量,存在静态池里,是不可变的,如果对字符串做操作是会新生成字符串的,因为这点所以才有了StringBuffer和StringBuilder,但是你的问题不在这里,final是来修饰这个引用的,加上final后,这个引用就不能再变了,至于该不该加,如果你需要对这个字符串做操作,当然是不加了,如果你这个值是定死了的,不会再变了,当然也可以不加,但是加上有两点好处,1,安全,你不能对这个引用再进行赋值,保证了他的不变,2,效率,通过jvm,加了final的变量和类执行的效率都高。。
回复 使用道具 举报
本帖最后由 anqi 于 2014-4-20 20:51 编辑

楼上楼下的都错了(我也错了),查了资料才知道,最下面有传智博客老师的讲解地址。                                                                   String str1 = "a"; String str2 = str1 + "bc";
System.out.println(str2 == "abc");
通过反编译可以知道Java中字符串的相加,其内部是使用StringBuilder类的append()方法和toString()方法来实现的.
StringBuildertoString()方法返回的字符串是通过构造函数创建的.。                                                                                                      final String str3 = "a";
String str4 = str3 + "bc";
System.out.println(str4 == "abc")
因为上面的并没有在运行时期进行字符串相加。两者都是常量,它们在编译的时候就确定了
也就是在编译完生成java文件的时候就相当于str="abc".根本没有在虚拟机中运算。
http://java.itcast.cn/news/20120921/13522688039.shtml






点评

哈哈哈。。。。这道题,真的很给力!  发表于 2014-4-20 20:55

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
本帖最后由 tacyjay在路上 于 2014-4-20 20:43 编辑
  1. class  
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 String str1 = "a";
  6.                 String str2 = str1 + "bc";
  7.                 System.out.println(str2 == "abc");//因为拿变量与常量比,所以这里是false  
  8.                
  9.                 final String str3 = "a";//被final修饰后,str3就是常量了,不可以再更改。
  10.                 String str4 = str3 + "bc";//所以此处,常量str3 +常量 "bc",结果自然是常量了,与常量"abc"一样。
  11.                 System.out.println(str4 == "abc");//两个常量字符串比较,所以是true
  12.         }
  13. }
复制代码
上面的是我自己考虑的,不顾网上搜了一下,貌似不对。。额。。。对不住了。。。楼主。。

答案先不删。。等大神回答。。。

点评

支持自己思考问题.虽然有时候答案不正确,可是自己参与进来了.黑马需要这样的人!!!  发表于 2014-4-20 21:38

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1 淡定

查看全部评分

回复 使用道具 举报 1 0
  1. String str1 = "a";
  2.                 String str2 = str1 + "bc";
  3.                 System.out.println(str2 == "abc");     //这里是false      
复制代码

栈中开辟一块空间存放引用str1;
         1) 堆中开辟一块空间存放一个新建的String对象"a";
         2) 引用str2指向堆中的新建的String对象"bc";
         3) str2所指代的对象地址为堆中地址,而常量"abc"地址在池中,输出为false;

  1. final String str3 = "a";
  2.                 String str4 = str3 + "bc";
  3.                 System.out.println(str4 == "abc");  //被final修饰过之后就是true了  为什么?
复制代码
栈中开辟一块空间存放引用str3;
        1) 根据编译器合并已知量的优化功能,池中开辟一块空间,存放合并后的String常量"a";
        2) 引用str4指向池中常量"bc";
        3) str4所指即池中常量"abc",输出为true;


评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
本帖最后由 lzhuas 于 2014-4-20 21:12 编辑

final作为常量,跟“bc”(也是常量)相加还是常量,跟第一个有区别
回复 使用道具 举报
tacyjay在路上 发表于 2014-4-20 20:23
上面的是我自己考虑的,不顾网上搜了一下,貌似不对。。额。。。对不住了。。。楼主。。

答案先不删。。等 ...

....呵呵:)
回复 使用道具 举报
anqi 发表于 2014-4-20 20:21
楼上楼下的都错了(我也错了),查了资料才知道,最下面有传智博客老师的讲解地址。                       ...

我看了半天也懵懵懂懂的...
回复 使用道具 举报
tacyjay在路上 发表于 2014-4-20 20:23
上面的是我自己考虑的,不顾网上搜了一下,貌似不对。。额。。。对不住了。。。楼主。。

答案先不删。。等 ...

我觉得你说的很好..哈哈!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马