0

I don't understand the ouptut of this code. When comparing two strings with same value (not assigned using new keyword), java returns true. But when I do it using new keyword and pass the value in the constructor, it prints false.

But when I use new keyword and instead of passing the value to the constructor I assign it in the next step. This time it returns true. Why?

class CheckStrings{
String s;
}


public class EQCheckTest {
  public static void main(String[] args) {
    String a1 = "pune";
    String a2 = "pune";
    String a3 = new String("pune");
    String a4 = new String();
    a4 = "pune";
    CheckStrings cs = new CheckStrings();
    cs.s = "pune";

    System.out.println(a1==a2); 
    System.out.println(a1==cs.s);
    System.out.println(a1==a3); 
    System.out.println(a1==a4); 
 }
}

OUTPUT:

    true
    true
    false
    true

Why a1==a3 false and a1==a4 true?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Manoj
  • 644
  • 12
  • 21
  • Strings are immutable. in this case when you assign `pune` to `a4` you are actually refering to the same instance of `pune` as `a1` and `a2` which where generated in the `String` pool at compile time, because they are literals. – SomeJavaGuy May 20 '16 at 07:12
  • The best way to check string equality test in java is to use equals() function. Example: new String("test").equals("test") – apadana May 20 '16 at 07:13
  • Assigning string stores in string pool. While creating string instance using contructor, assigns the memory in heap. Which results in true for all direct reference assignment and false for contructor argument. – gkbstar May 20 '16 at 07:15
  • In the line that says a4 = "pune"; you are essentially overwriting the value of a4 which was previously defined in String a4 = new String();. So a4, a1, a2 are basically like this: String aX = "pune" and they are pointing to the same literal (same reference) so they are equal. a3 is different because you are creating explicitly a new String object which has a different reference. – apadana May 20 '16 at 07:21
  • @apadana - Even if I am overwriting, a4 has already got a place on heap and so why is this difference between a3 and a4 – Manoj May 20 '16 at 07:28
  • 1
    @Manoj after you assign a4 a new value the previous new String() is orphan and will be garbage collected. So that "new String" from heap is gone and a4 is not holding to that anymore. In other words a4 doesn't have anything in the heap after this line: a4 = "pune". – apadana May 20 '16 at 07:31
  • @KevinEsche - So does this mean that whenever i assign a value to any `String` using `==` operator it will first check if any such string exist in String pool and if so, it will make that reference point to that string. – Manoj May 20 '16 at 08:37
  • @Manoj no, only for literal as `pune` is one and for constants. – SomeJavaGuy May 20 '16 at 08:43
  • @apadana - But when I print the `hashCode()` the value is same for all of them except for `cs.hashCode()`. But still `a1==cs.s` prints true. – Manoj May 20 '16 at 08:43
  • @Manoj `cs.hashCode` does print the hashcode of the class `CheckStrings` and not for the `String s` in the class. additionally `==` doesn´t assign something, it compares references. – SomeJavaGuy May 20 '16 at 08:44
  • @KevinEsche - Is there any way to print `hashCode` for `String s` in `CheckStrings` class? – Manoj May 20 '16 at 08:47
  • @Manoj override the `hashCode` method for `CheckStrings` and return `s.hashCode()` in there. – SomeJavaGuy May 20 '16 at 08:47

0 Answers0