1
public static void main(String[] args) {
    String m1 = args[0];
    System.out.println(m1.hashCode());
    System.out.println(args[0].hashCode());
    System.out.println("2345".hashCode());
    System.out.println(m1 == "2345");
}

If args[0] is "2345". The output is 1540226 1540226 1540226 false. Why false? Interned string can be compared with ==, right?

Matt Clark
  • 27,671
  • 19
  • 68
  • 123
  • Try `"2345".equals(m1)` – f_puras Feb 25 '16 at 20:40
  • 3
    You can compare Strings with `==`, but it compares their identities, not values. – bradimus Feb 25 '16 at 20:41
  • 3
    Strings passed as arguments are not interned. – Clashsoft Feb 25 '16 at 20:44
  • 1
    Possible duplicate of [How do I compare strings in Java?](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Matt Clark Feb 25 '16 at 20:44
  • 2
    @MattClark No, it's not. The OP is displaying an understanding of the difference between `==` and `equals`, and the role that interning has to play. They're just asking about a specific aspect of that. – yshavit Feb 25 '16 at 20:45
  • @yshavit, read the very first line of the accepted answer. `== tests for reference equality (whether they are the same object).` This answers this question, ergo, duplicate. – Matt Clark Feb 25 '16 at 20:46
  • 1
    Generally speaking: always assume `==` with `Object`s is _out to get you._ – Louis Wasserman Feb 25 '16 at 20:48
  • 1
    @MattClark But "Close as duplicate" means "This **question** has been asked before and already has an answer." This question is substantially different from that one, ergo not duplicate. – Reinstate Monica -- notmaynard Feb 26 '16 at 20:27

5 Answers5

2

Interned strings can only be compared using == to other interned strings, and will only return true if the interned string value is the same, ie

String a = "a";
String b = "b";
String a2 = "a";
String c = a;
String d = a;


a == a2; //true
a == "a"; //true
a == new String("a"); //false
c == d; // true;
(a + a) == "aa"; // false
ControlAltDel
  • 33,923
  • 10
  • 53
  • 80
1

You are checking a reference with value ? "2345".equals(m1) is right.

Raghu K Nair
  • 3,854
  • 1
  • 28
  • 45
1

A String is an object, so when you use ==, you're not checking for value equivalency, you're checking if one String object is in the same memory location as another.

Use .equals() when you want to test for value equivalency between objects

Severage
  • 33
  • 1
  • 7
1

Just because one instance of a string is interned, doesn't mean that others are. In this case, "2345" is a string constant and is thus automatically interned, but there's nothing that requires the JVM to automatically intern the arguments to main. To my knowledge, there's nothing that explicitly prohibits the JVM from doing that, but it doesn't seem to be happening.

yshavit
  • 42,327
  • 7
  • 87
  • 124
0

By "==" you are checking and comparing "reference" values of the String. Using "equals" works to compare the "contents" of two given strings.

hashCode returns similar values for m1, args[0], and "2345" because as interned strings, these have similar reference values as shown in your SOPs. Using a code example, this is how it is initializing:

String someString = "string_info"  
//Interning. Constant pool is checked for "string_info" and the reference is assigned to someString variable if "string_info" is found in constant pool.

However, when string is being passed as an argument, this is actually being created as a new string object. The new object is created in memory and hence your code m1 == "2345" returns false. Using example, this is how it is initializing:

String someString = new String("string_info") //a new String object is first created in memory and then assignment of "string_info" is referenced using constant pool look up.

Vishal
  • 1,963
  • 2
  • 20
  • 23