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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马刘涛 中级黑马   /  2012-7-11 00:02  /  1745 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黑马刘涛 于 2012-7-16 12:12 编辑

先附上一段代码
  1. public class fourtest {
  2.         public static String a = "";
  3.         public static String b;
  4.         public static String c = "2";
  5.         public static String d = "de";
  6.         public static String e = "d" + "e";
  7.         public static void main(String args[]){
  8.                 System.out.println(a+"2" ==  "2"); // false
  9.                 System.out.println(b+"2");// null2
  10.                 System.out.println(b+"2"=="null2");// false
  11.                 System.out.println(c+"");// "2"
  12.                 System.out.println(c+""=="2");// false
  13.                 System.out.println((c+"").equals("2"));//true
  14.                 System.out.println(d == e);//true
  15.         }
  16. }
复制代码
不知各位得出的运行结果和我注释有什么不同?equals方法和==不想多说了,看了网上一些文章有的说jvm对String优化如何如何,说的头头是道,运行结果却不像他说的那样。总之,记住以后对象比较用equals,基本数据类型比较用== 就行了。

5 个回复

正序浏览
回lss,既然会优化,那么第8行的输出结果为什么也是false?是否遇到空字符串编译器就不会做这样的事?
回复 使用道具 举报
基本数据类型用 == 是比较的值的大小,而引用数据类型用 == 是比较的内存地址 , equal是比较内存中的值。
回复 使用道具 举报
本帖最后由 周恺 于 2012-7-11 05:37 编辑

其实在我的理解里,<==>只是在栈内存中进行比较,如果用在引用类型上,就是在比较引用类型的地址.
而equals()方法,String已经重写了,可以比较String里面的内容.不知道楼主对c了解多少,C没有字符串的
概念,只是用字符数组实现字符串的功能.所以在使用==比较字符数组的时候,也只是在比较它们指针的
值,也就是两个数组0角标的位置.还有长度,而java是在C基础上改进的,所以我用C语言的观点来看:
01.public class fourtest {

02.        public static String a = "";

03.        public static String b;

04.        public static String c = "2";

05.        public static String d = "de";

06.        public static String e = "d" + "e";

07.        public static void main(String args[]){

08.                System.out.println(a+"2" ==  "2"); // false,将a看成是字符数组的0角标地址,当然不会等于另外一个字符数组的0角标地址咯,而且长度不一样.

09.                System.out.println(b+"2");// null2//不解释..要注意的是,null不是b的值,它是b的地址属性,它指向遥远的虚无宇宙..

10.                System.out.println(b+"2"=="null2");// false "null2"是一个字符串,在推内存中有明确的地址,只是栈内存中没有哥们愿意指向它.因上一条很容易得出false

11.                System.out.println(c+"");// "2"  ..这个没有什么好解释的.

12.                System.out.println(c+""=="2");// false  这个就很有意思了,在C语言中空字符串""是以在第零位为空字符的字符阵列表示,变成数组就是{'2',''}空字节也分配了
//1字节的内存空间,长度不同.
13.                System.out.println((c+"").equals("2"));//true  String将equals重写了,使之比较字符串内容,所以true

14.                System.out.println(d == e);//true 我想,你说的优化可能就在这里,当有两个字符串类型指向相同的内容时,jvm就在堆内存中只开辟一块空间,d和e所指向的内容相同
//所以它们在栈内存中存储的地址也相同,所以true.

15.        }

16.}
还有,二楼
  String a="ab";
  System.out.println(a==("a"+"b"));//答案是true.

点评

既然会优化,那么第8行的输出结果为什么也是false?是否遇到空字符串编译器就不会做这样的事?  发表于 2012-7-11 11:26

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
首先使用equals方法进行比较时,比较的是字符串的内容是否相同,这没有疑问吧
其次字符串在执行了“+”操作之后,无论其内是否相同,其结果都会指向新地址,
这就解释了8、10、12行的输出结果
对于字符串输出中有"null"的是由于在执行“+”操作时,java源码就是这么写的没有什么原因,该程序应该是
  1. public AbstractStringBuilder append(String str) {
  2.         if (str == null) str = "null";
  3.         int len = str.length();
  4.         if (len == 0) return this;
  5.         int newCount = count + len;
  6.         if (newCount > value.length)
  7.             expandCapacity(newCount);
  8.         str.getChars(0, len, value, count);
  9.         count = newCount;
  10.         return this;
  11.     }
复制代码
在AbstractStringBuilder这个抽象类中,可以理解9、11行(注意null与""是不一样的)
至于d和e在初始化时就是同样的值,所以自然指向同一个地址了
回复 使用道具 举报
大家可以讨论下得出如上运行结果的理由。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马