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");
System.out.print(s1.intern()==s2.intern());
intern()是什么东东?反正结果是true。如果没用过这个方法,而且训练有素的程序员会去看JDK文档了。简单点说就是用intern()方法就 可以用“==”比较字符串的内容了。在我看到intern()方法到底有什么用之前,我认为它太多余了。其实我写的这一条也很多余,intern()方法 还存在诸多的问题,如效率、实现上的不统一……
例子E:
String str1 = "java";
String str2 = new String("java");
System.out.print(str1.equals(str2));
无论在常量池还是堆中的对象,用equals()方法比较的就是内容,就这么简单!
字符串的比较用equals.
分享到:
相关推荐
测试时通常会用到一些hexstring参数,而在传递时需要转换成Base64String。这个小程序,能够很好的将HexString和Base64String相互转换。
扩展String功能方法:一直好忙,没有时间写属于自己的东西,但是看着一天天不更新心情也不是个滋味,只有从网上收罗一些比较好的东东贴上。
String的效率低于StringBuffer,开发时最好选用StringBuffer。
c++string用法详解用法详解,c++string各种函数工具,string函数很好用,像幅值,字符串函数的超全应用
共享struct2string由结构体变量获得其创建语句-struct2string.rar 本帖最后由 黄小标 于 2012-9-27 21:19 编辑 struct2string 顾名思义就是将struct变量变成字符串,此处字符串是此变量的创建语句。 不才,...
一、什么是Java中的String类? String类是Java中表示字符串的类。它是不可变的,一旦创建了一个字符串对象,就无法修改它。 二、String类和StringBuilder类有什么区别? String类和StringBuilder类的最主要区别在于...
讲多行的html转换成String 如:将下面的html代码转换成 你好的啊! 转换成: "<html>" +"<body>" +"你好的啊!<img src=\"1.jpg\">" +"</body>" +"</html>
可以将在数据库客户端编辑测试好的sql语句,直接转换为java代码中的String类型。
开发中我们经常需要将一个String和多个String值进行比较。直觉反应是使用||符号连接多个===完成,比如: 代码如下: if (string === ‘banana’ || string === ‘pineapple’) { fruitColor = ‘yellow’; } 这样能够...
教会你如何使用c++中的一个重要类型---string。
java中String的一些练习,能更加熟练String的方法,更加好的学习JAVA
字符串到16进制字符串之间的相互转换,能在通信程序中有很好的应用
对话框式的输入和输出,可以提供较好的界面处理。能通过弹出一个标准对话框,来提示用户。可以通过这个性质来实现具有对话框显示效果的数据输入和输出。
Android图片Bitmap和字符串String之间相互转换的工具类,外加项目代码,封装好的,直接可以用,
总结了String的常用方法,能让你更好的熟练应用String
每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。 StringBuffer 和 ...
C++ string 讲的很好。 值得一看
Json格式的字符串转成List、Array、Map、Object、List等,就是各种字符串转其他格式的方法.有个封装好的转换方法和一个我自己做的示例
看完了上面的文章再看下面的就比较好理解了 一般来说常用的函数代码 function $(id){ return typeof id==='string'?document.getElementById(id):id;} var GetBy = function (id) { return "string" == typeof id...
用纯C写的,char转string的方法,简洁易懂,很好用