views:

115

answers:

4

For instance

 String s = "Hello" + " World";

I know there are two strings in the pool "Hello" and "World" but, does: "Hello World" go into the string pool?

If so, what about?

String s2 = new String("Hola") + new String(" Mundo");

How many strings are there in the pool in each case?

+4  A: 

I believe in the first case the compiler will be clever and put the concatenated string in the pool (i.e. you'll have only 1 string there)

Brian Agnew
Is it true that in the second case, since there are no reference for the literals, the object in the pool is elegible for garbage collection and thus in the second case there won't be any object in the string pool?
OscarRyz
@Support - no. In the second case, the no string pool entry is created ... but not for the reasons you gave. Elibibility for garbage collection has nothing to do with implicit interning. (Indeed, for modern JVMs string in the String pool *may be* garbage collected, if they are not reachable via some other route.)
Stephen C
+5  A: 

Yes, if a String is formed by concatenating two String literals it will also be interned.

From the JLS:

Thus, the test program consisting of the compilation unit (§7.3):

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { static String hello = "Hello"; }

produces the output:

true
true
true
true
false
true

The important lines are 4 and 5. 4 represents what you are asking in the first case; 5 shows you what happens if one is not a literal (or more generally, a compile-time constant).

danben
...aaand how many strings are there in the pool in each case? :)
OscarRyz
3 in the first case since 3 things have been interned ("Hello", "world", and "Hello world"). In the second case you have only two literals, so 2.
danben
@Danben, in the first case there is only one String literal as the compiler has optmised the first two away. If you look at the compiles class file there is only one String literal.
Peter Lawrey
Ah, good point. I didn't consider compiler optimizations.
danben
A: 

By way of confirming @Brian Agnew's answer, I looked at this code:

public class InternTest {
    public static void main(String[] args) {
        String s = "Hello" + ", world";
        System.out.println(s);
    }
}

Nothing says the compiler has to do this, but Sun/Oracle's appears to do so. This behavior is required of string literals.

javap -c InternTest
Compiled from "InternTest.java"
public class InternTest extends java.lang.Object{
public InternTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc #2; //String Hello, world
   2:   astore_1
   3:   getstatic   #3; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:   aload_1
   7:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   10:  return
trashgod
No, it is required.
Tom Hawtin - tackline
@Tom Hawtin - tackline: If you can point me in the right direction, I'll update or delete.
trashgod
A: 

No. Only string literals are required to go into the pool. Compilers may optimize away the concatenation and may store additional string literals in the pool.

John
So, *How many strings are there in the pool in each case?*
OscarRyz
No, it is required.
Tom Hawtin - tackline