1
 public static void main(String[] args) {
        String[] arr = new String[5];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = "aaa" + i;
        }

    System.out.println(arr[0] == "aaa0"); // false 
    String s = "aaa0";
    System.out.println(s == arr[0]); // false 
    }

I have a few question regarding the topic could help me to understand

  1. What are logins behind the fact that String from string arrays don't automatically go to Sting pool, unlike string literals?

  2. Do I correctly understand that only string literals go to the String pool implicitly ?

  3. Do I correctly understand that string array from public static void main ( public static void main(String[] args) ) is not go to the String pool too ?

Tim Florian
  • 408
  • 1
  • 3
  • 13
  • 2
    It's not because it's in an array. It's because you're dynamically creating those `String`s (`arr[i] = "aaa" + i`). – resueman Feb 02 '17 at 21:47
  • 2
    @mstorkson he's talking about string pools though, so that is necessary to show his thinking. – Zircon Feb 02 '17 at 21:51
  • 1
    @mstorkson In my case, making comparison through == important to show string pool action ; through equals() everything will be "true" - the string in String pool and outside it. – Tim Florian Feb 02 '17 at 21:52
  • **#2:** Correct. --- **#1:** See #2. --- **#3:** Correct, aka see #2. – Andreas Feb 02 '17 at 22:11

3 Answers3

3

The compiler transforms that for loop under the covers!

And the resulting bytecode will use a new StringBuilder for each loop iteration... Resulting in "newly" created string objects!

Meaning; in "reality; your loop looks "more" like:

for (int i = 0; i < arr.length; i++) {
  StringBuilder builder = new StringBuilder("aaa");
  builder.append(i);
  arr[i] = builder.toString();
}

(see here on the theoretical background)

That is one of the reasons that using == to compare strings has such a bad reputation... As it tends to lead to unexpected results.

And regarding your comment: the point is not the array you are using (where: you should not be writing into the array passed to main - you can, but it is bad practice).

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thx for your attention ! what about public static void main ( String[] args )? args String arr has the same logic ? Or it is some kind exception for the compiler regarding my question ? – Tim Florian Feb 03 '17 at 08:40
  • You are very welcome. I made some updates, and in case you like my answer, please consider accepting at some point ;-) – GhostCat Feb 03 '17 at 08:45
2

You can call the intern() method to enforce String pooling, i.e. to store only one copy of each distinct string value. Check this out:

public static void main(String[] args) {
    String[] arr = new String[5];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = ("aaa" + i).intern();
    }

    System.out.println(arr[0] == "aaa0"); 
    String s = "aaa0";
    System.out.println(s == arr[0]); 
}
Grzegorz Górkiewicz
  • 4,496
  • 4
  • 22
  • 38
0

Use equals() if you want to compare THE CONTENT of two objects. Here are more of an explication

The “==” operator

In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.

The equals() method

The equals method is defined in the Object class, from which every class is either a direct or indirect descendant. By default, the equals() method actually behaves the same as the “==” operator – meaning it checks to see if both objects reference the same place in memory. But, the equals method is actually meant to compare the contents of 2 objects, and not their location in memory.

System.out.println(arr[0].equals("aaa0")); // It give you True
System.out.println(s == arr[0]); // It give you false
Gatusko
  • 2,503
  • 1
  • 17
  • 25