-3

I wrote the following code:

String s="Rahul";
String s2=s.concat(" Shukla");
String s3="Rahul Shukla";
System.out.println(s2==s3);

I was expecting true as the output of s2==s3, but it becomes false. As I think s2 and s3 are pointing to the same object in the string constant pool, so s2==s3 should evaluate to true. Can anyone please tell me what is really going on here?

David Berg
  • 1,958
  • 1
  • 21
  • 37

5 Answers5

3

First of all, unless you care about JVM internals and unreliable "guarantees", don't use ==. Just don't.

Secondly, when calling concat with " Shukla", the result is not in the constant pool. Rahul and Shulka are, but their concatenation is a new String on the heap:

Strings computed by concatenation at run time are newly created and therefore distinct.

+ as an operator is different since it's not a method call, in the case where both of its operands are known to be constant (by being a string literal):

Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.

Literal strings within the same class (§8 (Classes)) in the same package (§7 (Packages)) represent references to the same String object (§4.3.1).

All quotes are from the JLS, Version 8, section 10.3.5.

Community
  • 1
  • 1
nanofarad
  • 40,330
  • 4
  • 86
  • 117
0

If you did create every string using new String(somestring).intern() then you can use the == operator to compare two strings, otherwise equals() or compareTo methods can only be used. equals() method is present in the java.lang.Object class and it is expected to check for the equivalence of the state of objects.

Check this link : How do I compare strings in Java?

Community
  • 1
  • 1
Shiladittya Chakraborty
  • 4,270
  • 8
  • 45
  • 94
0

Since String is immutable concat() method will create new string object. but s3 will refer to an object which is in string pool. So s2==s3 it will return false

Rahman
  • 3,755
  • 3
  • 26
  • 43
0

The s3 variable is created in the pool and s2 in the heap since == compare the reference the are not equal which gave you false.

String s3="Rahul Shukla";  

Is creatd in the poot as s3 value can be determined at compiletime

String s2=s.concat(" Shukla");

is created in the heap because if you see the source code of concat() it returns new String()

singhakash
  • 7,891
  • 6
  • 31
  • 65
0

Interestingly, the specification of concat has changed between Java 7 and Java 8.

The Java 7 Specification says:

If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created...

Whereas the Java 8 Specification says:

If the length of the argument string is 0, then this String object is returned. Otherwise, a String object is returned that represents a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.

However, the implementation doesn't seem to have changed. Here is the code.

public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    int len = value.length;
    char buf[] = Arrays.copyOf(value, len + otherLen);
    str.getChars(buf, len);
    return new String(buf, true);
}

This means that if you use == to compare the result of s.concat(" Shukla") with s3 you will get false, but this is not strictly speaking guaranteed by the specification.

However, as others have pointed out, you do not need to care about this. You should just compare strings using .equals and forget about the details.

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116