0
String s1="Hello";
s1=s1.concat("World");
String s2="HelloWorld";
    
System.out.println(s1);
System.out.println(s2);
System.out.println(s2==s1); //false

As after concatenating, the "HelloWorld" string is created in the string constant pool and we are making another string with the same word "HelloWorld" then it is already present in the string constant pool hence it returns the existed reference. So, why my code is giving false in the output?

String s1="Hello";
    String s2="HelloWorld";
    
    s1=s1.concat("World");

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

    String s2="HelloWorld";

    
    System.out.println(s1);
    System.out.println(s2);
    System.out.println(s2==s1);//false

why false?? why they are pointing to different ref. As the word is already present in the string constant pool. then if we forming a new string object with the same value then it should point to the already present object.

Dekay
  • 11
  • 6
  • what language is this? – Gudarzi Dec 21 '20 at 16:12
  • language - Java – Dekay Dec 21 '20 at 16:13
  • == is a equality operator which will try to compare the references of the objects.You should instead use .equals() to compare contents of 2 strings – Dev-vruper Dec 21 '20 at 16:14
  • I guess `s1.concat()` doesn't return anything so use `s1.concat("World");` instead of `s1=s1.concat("World");` – Gudarzi Dec 21 '20 at 16:14
  • 2
    "*As after concatenating, the "HelloWorld" string is created in the string constant pool*" no, result of concatenation will be placed automatically in string pool only if (a) you are using `+` as concatenation operator, not `concatenate` method and (b) if you are concatenating *compile time constants*. None of those conditions are fulfilled. – Pshemo Dec 21 '20 at 16:24
  • String s1="Hello"; s1=s1+"World"; String s2="HelloWorld"; System.out.println(s1); System.out.println(s2); System.out.println(s2==s1);//false – Dekay Dec 21 '20 at 16:26
  • 1
    At `s1+"World"` `s1` is not *compile time constant* because compiler can't be sure of `s1` value as it is not `final`. Try with `final String s1="Hello";` and see the difference. You would also need to declare new variable for result of concatenation since you can't reassign that result back to already initialized s1. So you will need something like `String s3 = s1 + "World";` and then compare `s2 and s3` not `s2 and s1` – Pshemo Dec 21 '20 at 16:27
  • I also found an interesting read on the same topic about the concatenation of strings and java string pool. not sure if it would help? https://stackoverflow.com/questions/44037516/how-java-string-pool-works-when-string-concatenation – YHStan Dec 21 '20 at 16:41
  • @Pshemo - Greate comments! You haven't left anything to be posted as an answer . – Arvind Kumar Avinash Dec 21 '20 at 17:08
  • 1
    @ArvindKumarAvinash I am sure that there is somewhere answer of Jon Skeet which explains it better. Now main goal is to find that answer and link this question to it :) – Pshemo Dec 21 '20 at 19:10

5 Answers5

3

The strings have not an equal identity by default. A string from the string pool is only returned if the string is interned.

All String values or String concatenations whose results are solely from constant expressions are interned automatically. A constant expression is an expression whose value is known at compile time. That includes:

  • literals; and
  • final variables of primitive types or the String class.

Examples:

String a = "Hello" + "World";   // 'HelloWorld'
String b = "Hi" + 23 + "There"; // 'Hi23There'
final int i = 47 + 100;
String c = "Number" + i + '!';  // 'Number147!'

This is defined in the Java Language Specification, § 15.28.

Your use case does not fulfill these requirements, so your result is false. You can trigger string interning by calling Strings intern() method. If you had written s1 = s1.concat("World").intern(); instead, then the result would be true.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
2

You need to use equals instead of == , so your code must look like System.out.println(s2.equals(s1))

We can use == operators for reference comparison (address comparison) and .equals() method for content comparison. In simple words, == checks if both objects point to the same memory location whereas .equals() evaluates to the comparison of values in the objects.

Aladin
  • 586
  • 3
  • 15
  • No i'm comparing the reference. so thats why using ==. – Dekay Dec 21 '20 at 16:14
  • String s1="Hello"; s1=s1.concat("World"); JVM takes the string s1("Hello") and concate it with ("World"), Now a new object is created whose value is "HelloWorld" then JVM will check in the string constant pool, if it si not present then it will create a new object and return the reference String s2="HelloWorld" and again we are making a new String with the same value then it should point to the built object. – Dekay Dec 21 '20 at 16:16
1

You are creating two objects s1 and s2 . So when you do

s2==s1

you are comparing references of those 2 objects, which will always return false as both objects are seperate.

If comparing contents of a string , try implementing the .equals() method.

s2.equals(s1)

Dev-vruper
  • 421
  • 3
  • 12
  • I saying that why they are not pointing to the same object/reference? – Dekay Dec 21 '20 at 16:24
  • When you do `String s1='Hello'`, a new object is created in the pool with value 'Hello' , also when you try to create `String s2='HelloWorld'`, it tries to find whether a object already exists in Pool with value 'HelloWorld' .As its not present , a new object is created and assinged to s2. – Dev-vruper Dec 21 '20 at 16:32
1

s1 and s2 are 2 different references pointing towards 2 different addresses. Therefore s1==s2 will return false always (since different addresses).

Taćhe Boy
  • 11
  • 1
0

This is because the concat() method returns a new String object

public String concat(String str) {
    if (str.isEmpty()) {
        return this;
    }
    return StringConcatHelper.simpleConcat(this, str);
}

If you used the "+" operator instead this will result in your expected output:

String s1 = "Hello" + "World";
String s2 = "HelloWorld";

System.out.println(s1 == s2); // true

Hope this helps for your understanding, but for real world usage always stick to .equals() when comparing String values:

System.out.println(s1.equals(s2));
Arshad
  • 1