首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Linux频道
中国IT教育
Google
首页 资讯动态 认证考试 新手入门 核心技术 高级技术 J2EE J2ME Java&XML 开源技术 其他技术 RSS订阅 论坛 专题
您现在的位置: 中国IT实验室 >> Java >> 新手入门 >> 基础入门 >> 正文

String对象真的可以用==比较吗?

    前一阵子用findbug插件寻找bug,发现了一个很奇怪的bug,内容如下:

    subTargetNode.addText( (null == subTarget || "" == subTarget.trim() ) ? "_blank" : subTarget  );

    subTargetNode.addText( (null == subTarget || "" == subTarget.trim() ) ? "_blank" : subTarget  );
[ES] Comparison of String objects using == or != [ES_COMPARING_STRINGS_WITH_EQ]
This code compares java.lang.String objects for reference equality using the == or != operators. Unless both strings are either constants in a source file, or have been interned using the String.intern() method, the same string value may be represented by two different String objects. Consider using the equals(Object) method instead.

    String不是immutable的类吗?而且还有String Pool,在JVM中相同内容的String对象不是只有一个吗?为什么不可以用==比较相等?东东在网上搜索了一篇文章又查了一下Java Language Specification,有点明白了,

    那篇文章如下:

    看例子:例子A:
    String str1 = "java";
    String str2 = "java";
    System.out.print(str1==str2);
   地球上有点Java基础的人都知道会输出false,因为==比较的是引用,equals比较的是内容。不是我忽悠大家,你们可以在自己的机子上运行一 下,结果是true!原因很简单,String对象被放进常量池里了,再次出现“java”字符串的时候,JVM很兴奋地把str2的引用也指向了 “java”对象,它认为自己节省了内存开销。不难理解吧 呵呵
    例子B:
    String str1 = new String("java");
    String str2 = new String("java");
    System.out.print(str1==str2);
     看过上例的都学聪明了,这次肯定会输出true!很不幸,JVM并没有这么做,结果是false。原因很简单,例子A中那种声明的方式确实是在 String常量池创建“java”对象,但是一旦看到new关键字,JVM会在堆中为String分配空间。两者声明方式貌合神离,这也是我把“如何创 建字符串对象”放到后面来讲的原因。大家要沉住气,还有一个例子。
    例子C:
    String str1 = "java";
    String str2 = "blog";
    String s = str1+str2;
    System.out.print(s=="javablog");
再看这个例子,很多同志不敢妄言是true还是false了吧。爱玩脑筋急转弯的人会说是false吧……恭喜你,你会抢答了!把那个“吧”字去掉你就完 全正确。原因很简单,JVM确实会对型如String str1 = "java"; 的String对象放在字符串常量池里,但是它是在编译时刻那么做的,而String s = str1+str2; 是在运行时刻才能知道(我们当然一眼就看穿了,可是Java必须在运行时才知道的,人脑和电脑的结构不同),也就是说str1+str2是在堆里创建的, s引用当然不可能指向字符串常量池里的对象。没崩溃的人继续看例子D。
    例子D:
    String s1 = "java";
    String s2 = new String("java");
 

[1] [2] [3] [4] 下一页

【责编:landy】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Java 频道导航