Using == when comparing objects

2020-04-08 06:41发布

Recently in a job interview I was asked this following question (for Java):


String s1 = "abc";
String s2 = "abc";

What is the return value of

(s1 == s2)

I answered with it would return false because they are two different objects and == is a memory address comparison rather than a value comparison, and that one would need to use .equals() to compare String objects. I was however told that although the .equals(0 methodology was right, the statement nonetheless returns true. I was wondering if someone could explain this to me as to why it is true but why we are still taught in school to use equals()?

标签: java
2楼-- · 2020-04-08 07:06

You should continue to use equals() when testing string equality. Java makes no guarantees about identity testing for strings unless they are interned. The reason the s1 == s2 in your example is because the compiler is simply optimizing 2 literal references in a scope it can predict.

3楼-- · 2020-04-08 07:07

java will intern both strings, since they both have the same value only one actual string instance will exist in memory - that's why == will return true - both references point to the same instance.

String interning is an optimization technique to minimize the number of string instances that have to be held in memory. String literals or strings that are the values of constant expressions, are interned so as to share unique instances. Think flyweight pattern.

4楼-- · 2020-04-08 07:11

The reason is strings are interned in Java. String interning is a method of storing only one copy of each distinct string value which is immutable. Interning string makes some string processing tasks more efficient. The distinct values are stored in a string intern pool. (From wiki)

5楼-- · 2020-04-08 07:12

Since you are not actually creating new instances of String objects for either one of these, they are sharing the same memory space. If it were String s1 = new String("abc"); String s2 = new String("abc"); the result would be false.

Deceive 欺骗
6楼-- · 2020-04-08 07:19

String constants are interned by your JVM (this is required by the spec as per here):

All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

This means that the compiler has already created an object representing the string "abc", and sets both s1 and s2 to point to the same interned object.

7楼-- · 2020-04-08 07:26

You're right that == uses memory address. However when the java compiler notices that you're using the same string literal multiple times in the same program, it won't create the same string multiple times in memory. Instead both s1 and s2 in your example will point to the same memory. This is called string interning.

So that's why == will return true in this case. However if you read s2 from a file or user input, the string will not automatically interned. So now it no longer points to the same memory. Therefor == would now return false, while equals returns true. And that's why you shouldn't use ==.

登录 后发表回答