在Java中使用'=='代替.equals进行字符串比较

10

Marcos在你提供的问题的回答中提供了一个很好的例子 - Matthew Flaschen
相关链接:https://dev59.com/Gmkw5IYBdhLWcg3ws873#9698305 - Michael Berry
4个回答

40

这是因为你很幸运。在Java中,== 操作符检查的是引用相等性:如果指针相同就返回 true。它不检查内容的相等性。编译时发现的相同字符串会被合并成一个单独的 String 实例,因此它适用于 String 字面量,但不适用于在运行时生成的字符串。

例如,"Foo" == "Foo" 可能有效,但 "Foo" == new String("Foo") 不行,因为 new String("Foo") 创建了一个新的 String 实例,并且打破了任何可能的指针相等性。

更重要的是,在实际程序中,你处理的大多数 Strings 是在运行时生成的。文本框中的用户输入是在运行时生成的。通过套接字接收的消息是在运行时生成的。从文件中读取的内容是在运行时生成的。因此,如果要检查内容的相等性,使用 equals 方法而不是 == 操作符非常重要。


3
额外补充一下,"foo" == "foo" 之所以可行,是因为所有的字符串字面量都是被 interned 的。http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern() - Matt Briggs

10

有没有人能给我一个“==”运算符失败的例子?

示例1:

String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // false

示例 2:

Integer a=1000,b=1000;
System.out.println(a == b); // false

1
猜想那会起作用。但是字符串不是不可变的吗?因此,它们不应该被池化吗? - Aillyn
字面字符串被池化。 - Bruno Reis
2
"Hello" == "Hello" ==> true。然而,new String("Hello")将为一个对象分配一些内存,并且再次执行相同的操作将在另一个地方为另一个对象分配更多的内存。由于“==”运算符比较引用,它将返回false。 - Bruno Reis
3
小整数(-127到127)也会被“interned”(即内部化)。因此,对于a = 100,整数示例实际上会返回true。(这是一个实现细节,但我不想依赖它)。 - Thilo
1
@pessimopoppotamus - 只有字符串字面量会自动进行内部化。其他字符串实例仅在应用程序显式调用String.intern()时进行内部化。(这是一种效率问题:内部化在许多方面都很昂贵。) - Stephen C

4
当您这样做时,实际上是创建“字符串文字”:
String s1 = "Hello";
String s2 = "Hello";

编译器会找到相同的字符串常量,然后通过在堆中保留一个实例并使栈中的所有变量指向它来进行优化。因此,执行==将返回true,因为它们指向相同的内存地址。
这样做时,您正在创建字符串对象:
String s1 = new String("Hello");
String s2 = new String("Hello");

实例化将为它们在堆上创建独特的空间,并且堆栈变量将指向这些单独的位置。因此,使用.equals()时它们将是相等的,因为它们的值相同,但使用==时它们将不相等,因为它们是堆内存空间中的不同对象。

4

经验丰富的Java开发人员很少使用new String(String),但这个问题也会在其他情况下出现。例如:

String hello = "Hello"
String hell = hello.substring(0, 4);
System.err.println("Hell" == hell);  // should print "false".

在实际应用中,大多数String实例都是通过从其他String中取子串或者通过字符数组构造而成的。很少有应用程序只使用作为字面量创建的String实例。


1
使用“y = new String(x)”(其中x是一个字符串)的一个原因是允许垃圾回收,当x是一个非常大的字符串的子字符串时。如果只使用“y = x”,那么只要y被引用,这个非常大的字符串就无法进行垃圾回收。如果使用“new String(x)”,则会创建一个不引用原始大字符串的新字符串。 - Thomas Mueller
4
没错,但就我的经验来看,这很少是必要的。如果不必要,那么实际上它就是一种反优化。 - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接