-3

I'm a newbie to Java. Now I'm studying "==" operator with String.

I know that in java, string literals are stored in String Pool in Heap area to achieve immutability and memory saving. And I know that if I use the "new" keyword, it is stored in the Heap area, not the String pool.

In the code below case_1, case_2, case_3 all return the same string literal. So I expected everything to print true. But for case_1 it printed false.

My question is:

  • Since case_1, 2, and 3 all return the same string literal, they all point to the same address in the string pool, so it should output true, but why does it output false for case_1?

If possible, please answer with reference to the String pool in the Heap.

Thanks!

public class Main {
    public static void main(String[] args) {
        MyString ms = new MyString();

        String str1 = ms.getString1(10);
        String str11 = ms.getString1(10);

        String str2 = ms.getString2();
        String str22 = ms.getString2();

        String str3 = 10 + "";
        String str33 = 10 + "";

        System.out.println(str1 == str11); // case_1
        System.out.println(str2 == str22); // case_2
        System.out.println(str3 == str33); // case_3
    }
}

class MyString {
    String getString1(int n) {
        return n + "";
    }

    String getString2() {
        return 10 + "";
    }
}

I expected the following

true
true
true

but the actual output like this

false
true
true
ko-hs
  • 1
  • 1
  • @MadProgrammer The linked question is not a duplicate. I suggest to reopen it. – Ted Klein Bergman Aug 24 '23 at 06:38
  • @TedKleinBergman Feel free to cast a re-open vote – MadProgrammer Aug 24 '23 at 07:01
  • @MadProgrammer I can't cast another; I've already cast one before for this question due to it being closed as duplicated with the same question. – Ted Klein Bergman Aug 24 '23 at 07:06
  • 1
    Do you understand what the term “string literal” means? None of your methods returns a string literal. There is only one string literal in your code (`""`) but no `return "";` statement. Neither `n + ""` nor `10 + ""` are string literals. – Holger Aug 24 '23 at 09:38
  • @Holger You are correct. I was confusing String and String literal. Now I understand that a string literal is a fixed string value within the code. But based on this understanding, `10 + ""` is a fixed string value within the code, so it is a string literal. Isn't that correct? – ko-hs Aug 24 '23 at 10:56
  • 1
    A string literal is a syntactic construct of the source code. Only `"10"` is a string literal. In contrast, `10 + ""` is an *expression*, but its value is a *compile-time constant*. So both, `"10"` and `10 + ""` are compile-time constants with the same value and hence, guaranteed to refer to the same `String` object at runtime. The source code form doesn’t matter, in other words, it doesn’t need to be a string literal. It has to be a compile-time constant, as specified in [this section of the specification](https://docs.oracle.com/javase/specs/jls/se20/html/jls-15.html#jls-15.29) – Holger Aug 24 '23 at 11:06

1 Answers1

1

The string pool is for strings known at compile-time. Case 2 and 3 are known.

Case 2 always return the string 10 + "", so it can be interned. Case 3 always store the string 10 + "", so it can be interned.

Case 1, however, returns n + "" where n can be anything. It wouldn’t make sense for the compiler to store all strings possible for all values of n. Therefore, it is stored in the heap.

Even if in this simple case, we know that case 1 is 10 + "" as well, but it would be a bit complicated to go over all functions in your program to try and pre-calculate strings.

Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50