我有一个关于在 Java 中将字符串与空字符串进行比较的问题。如果我将字符串与空字符串与 ==
或 equals
进行比较,是否有区别?例如:
String s1 = "hi";
if (s1 == "")
或者
if (s1.equals(""))
我知道应该将字符串(和一般对象)与 equals
进行比较,而不是 ==
,但我想知道它对空字符串是否重要。
原文由 user42155 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个关于在 Java 中将字符串与空字符串进行比较的问题。如果我将字符串与空字符串与 ==
或 equals
进行比较,是否有区别?例如:
String s1 = "hi";
if (s1 == "")
或者
if (s1.equals(""))
我知道应该将字符串(和一般对象)与 equals
进行比较,而不是 ==
,但我想知道它对空字符串是否重要。
原文由 user42155 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
不可靠,因为它测试引用相等性而不是对象相等性(并且 String 不是严格规范的)。
更好,但可能会出现空指针异常。更好的是:
没有空指针异常。
编辑: 好的,问题是关于 规范形式 的问题。本文将其定义为:
给你一个实际的例子:拿一组有理数(或“分数”,它们通常被称为)。有理数由分子和分母(除数)组成,两者都是整数。这些有理数是等价的:
3/2、6/4、24/16
有理数通常写成 gcd(最大公约数)为 1。因此所有这些都将简化为 3/2。 3⁄2 可以看作是这组有理数的 规范形式。
那么当使用术语“规范形式”时,它在编程中意味着什么?它可能意味着几件事。以这个虚构的类为例:
MyInt 类的哈希码是该类的规范形式,因为对于 MyInt 的所有实例的集合,您可以采用任意两个元素 m1 和 m2,它们将遵循以下关系:
这种关系是规范形式的本质。出现这种情况的一种更常见的方式是在类上使用工厂方法,例如:
实例不能直接实例化,因为构造函数是私有的。这只是一个工厂方法。工厂方法允许你做的事情是:
基本上,工厂方法抽象了对象创建,我个人认为强制所有构造函数为私有以强制使用此模式将是一个有趣的语言功能,但我离题了。
你可以用这个工厂方法做的是缓存你创建的实例,这样对于任何两个实例 s1 和 s2 它们都服从以下测试:
所以当我说 String 不是严格规范的时候,它意味着:
但正如其他人指出的那样,您可以使用以下方法更改此设置:
并且可能:
所以你不能完全依赖引用相等性,所以你根本不应该依赖它。
作为对上述模式的警告,我应该指出,由于序列化,使用私有构造函数和工厂方法控制对象创建并不能保证引用相等意味着对象相等。序列化绕过了正常的对象创建机制。 Josh Bloch 在 Effective Java 中介绍了这个主题(最初是在第一版中,他谈到了后来成为 Java 5 语言特性的类型安全枚举模式),您可以通过重载(私有)readResolve() 方法来解决这个问题。但这很棘手。类加载器也会影响这个问题。
无论如何,这是规范形式。