Reputation: 4642
Here's my code:
public class StringExperimenter {
public static void main(String[] args) {
String s1 = "This is" + "limafoxtrottango";
String s2 = "This is" + getName();
String s3 = "This is" + getName();
System.out.println(s1 == s2); // prints false
System.out.println(s3 == s2); // prints false
}
private static String getName() {
return "limafoxtrotango";
}
}
Now, I understand that s1
is evaluated by the compiler at compile-time and it is then interned.
But, what about s2
and s3
? Both of these are created at runtime. So, are two different strings created? Do these strings go to the constant string pool?
Upvotes: 1
Views: 163
Reputation: 25903
s1
is completely interned, i.e.
This islimafoxtrottango
as the string concatenation happens at compile-time.
The other two require a method call, only the intermediate strings are interned. The concatenation is not, as it happens at runtime.
You also observed that already, as
System.out.println(s1 == s2); //prints false
System.out.println(s3 == s2); //prints false
would otherwise print true
.
You can check the JLS (Java Language Specification) for details on this behavior, every valid Java implementation must do it exactly that way.
From JLS§15.28 about Constant Expressions:
A constant expression is an expression denoting a value of primitive type or a
String
that does not complete abruptly and is composed using only the following:
The following list contains more or less:
- literals
- operators like +
- constant variables
Importantly, it does not list any method calls, even if they return a constant value.
It also states that:
Constant expressions of type
String
are always "interned" so as to share unique instances, using the methodString.intern
.
Upvotes: 4
Reputation: 4545
If you compile your class from the command line like this:
javac.exe -g StringExperimenter.java
And then use javap.exe -v StringExperimenter.class
to study the resulting class file, then you will see, that the following byte code is generated:
...
public static void main(java.lang.String...);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=3, locals=4, args_size=1
0: ldc #2 // String This islimafoxtrottango
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String This is
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder
15: invokestatic #7 // Method getName:()Ljava/lang/String;
18: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder
21: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_2
25: new #3 // class java/lang/StringBuilder
28: dup
29: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
32: ldc #5 // String This is
34: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder
37: invokestatic #7 // Method getName:()Ljava/lang/String;
40: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder
43: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
46: astore_3
47: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
50: aload_1
51: aload_2
52: if_acmpne 59
55: iconst_1
56: goto 60
59: iconst_0
60: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V
63: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
66: aload_3
67: aload_2
68: if_acmpne 75
71: iconst_1
72: goto 76
75: iconst_0
76: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V
79: return
...
Based on this, I would say that s1 is interned whereas s2 and s3 are computed (using StringBuilder
) at runtime.
Upvotes: 2
Reputation: 5711
As Conspect of String is immutable in java. Above result are true. Whenever we append something in one string by concating creates a new reference in the String intern pool.
So if compare all above 3 Strings using equals methods its return True but false if compare using == operator.
Upvotes: 1