Java字符串相等
用多了像Java这样的高层次语言容易让人变得懒惰和想当然。在C语言里,==
非常纯粹,没人会用它来判断两个字符串是否相同。
但在Java里却会经常不经意地出现诸如if (str == "") {...}
这样的代码。
这样的代码有时候是对的。但不对的时候,这错误又很难发现。今天遇到的一个bug就是用==
来判断字符串相等导致的。
Java里的字符串类是String。String类型的变量都是引用型变量。直接用==
来比较两个引用变量的话,实际比较的是它们所引用的对象的地址,
只有二者指向同一个对象时才会相等,并不能判断两个对象的内容是否相同。从这个角度说,试图用==
比较两个字符串的内容其出发点就是错误的。
但为什么容易犯这样的错误呢?主要是存在一些误导。第一,有些语言确实是用==
来判断两个字符串内容是否一样的。第二,在有的高级语言里,允许类进行操作符重载(C++,说的就是你!),将==
重新实现为比较两个对象的内容。第三,Java语言本身支持用+
和+=
操作符对字符串进行连接,这也容易让人觉得字符串可以像数值那样比较相等。
还有最坑爹的一个误导就是,有时候用==
比较Java字符串竟然会得到正确的结果!
Java程序在运行的时候会维护一个字符串池。这个池子里包括程序中所有的字符串常量。如果两个String变量内容是相同的常量,那么它们指向的都是字符串池中的那个常量的地址。
结果用==
比较它们时确实会相等。String类还有一个intern方法,可以将任意字符串加入池中。上述机制的主要出发点在于节省内存,但由此也导致了一些混乱,使得有些程序员侥幸逃过了用==
比较字符串的惩罚。
但我们不能存侥幸心理。以后比较字符串内容时完全不要用==
,而应该用字符串类的equals方法。更多细节可参见http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java。
在Objective-C里,也有类似的问题。我记得我在写iOS应用的时候也出现过用==
比较字符串内容的代码,不过好在及时纠正了。
如果想要说些什么,欢迎发邮件给我。