Java 语言的几个缺陷之二: 字符串比较
对于面向对象的语言不知道除了 Java 还有没别的语言会拿怎么比较两个字符串相等频频作为面试题来考. 原本是在编程语言中两个字符串内容是否相等时用 ==
比较时却可能是不对的. 在 Java 中
"ab" == "ab" //true "ab" == "new String("ab") //false "ab" == String.value("ab") //true new String("ab").equals(new String("ab")) //true new String("ab").intern() == new String("ab").intern() //true
在 Java 中明明看到两个字符串内容一样用 ==
进行比较多数时候不是你想要的结果, 只有用 equals()
方法才是王道. 使用 Java 的字符串必须了解它内部是怎么存储的. 比于上面的结果我不作细说, 主要涉及到字符串常量池及内部状态, ==
比较引用, equals()
比较内容. Java 还常常对 equals
比较字符串津津乐道, 而我仍然认为它是语言设计上的一个缺陷, 所以 JVM 上的其他编程语言如 Groovy, Scala 纷纷倒勾, 无一不是用==
来比较字符串的内容, 它们也提供字符串引用的比较, 但多少人实际关心两个字符串的引用是否相同呢, 反正字符串设计的是 Immutable 的. 若说是因为 Java 不支持操作符的重载, 但可以像 Scala, Groovy 那样在编译器上下功夫的. 最终我想依然是受累于 100% 源代码与二进制的兼容性, 改进的话会造成早先代码的行为错乱. Groovy 和 Scala 在比较两个字符串只管用 ==
号, 它们能先判断引用是否相等, 然后再调用 equals()
方法来比较, 所以 ==
比较内容时还不怕 null
值的干扰. Groovy 在调用 equalse()
之前会用 compareTo
先判断. 顺道一下, Groovy 想要比较引用时用 is()
方法, 如
groovy:000> "ab".is("ab") ===> true groovy:000> "ab".is(new String("ab")) ===> false
而在 Scala 中要比较两引用时用 eq
或 ne
方法,如
scala> "ab" eq "ab" res13: Boolean = true scala> "ab" eq new String("ab") <console>:12: warning: comparing a fresh object using `eq' will always yield false "ab" eq new String("ab") ^ res14: Boolean = false scala> val v = new String("ab") v: String = ab scala> "ab" eq v res15: Boolean = false scala> "ab" ne v res16: Boolean = true
Scala 也很聪明, 如果用 eq 时有一边是刚 new
出来的对象, 那么肯定是 false
C# 用 Object.referenceEquals()
来比较两个对象的引用, 看
char[] array = { 'a', 'b' }; "ab" == new String(array); //true Object.ReferenceEquals("ab", "ab"); //true Object.ReferenceEquals("ab", new String(array)); //false
其他类似于脚本的语言只会更忠实的用==
比较内容.
要说能寻找到不能用 ==
比较字符串的踪迹那就是 C/C++ 了, 传统 C 字符串必须用 strcmp
函数比较, C++ string 类型用 compare
函数. 其实 std:string 已对 ==
操作符进行了重载, 所以也可以放心的用 ==
比较两字符串的内容.
字符串是那么如此最常用的一种结构, Java 却使得它们在比较内容上让人如此迷惑, 造就了一道经典面试题. 容易出错而违反常规的东西不是什么好玩意, 一切当顺其自然才是.
本文文字及图片出自 gloveangels.com
你也许感兴趣的:
- 【外评】不要把 Rust 写成 Java
- “甲骨文牌”Java正在死亡
- 您现在可以像运行 Python 一样运行 Java
- 从 Java 8 迁移到 Java 17 (二):Java 中值得注意的 API 变化
- 从 Java 8 迁移到 Java 17:新功能大汇总
- Oracle 再夺 Java 命?大公司用 Java 要小心了!
- 【程序员搞笑图片】java haters
- Java 22 新功能特性及示例
- Java 22 中最令人兴奋的 3 个功能
- 【译文】Java 21 – Kotlin 是否正在消亡?
你对本文的反应是: