6

In C++, the best canonical way to create a multiline string of which I am aware is to create adjacent strings and let the compiler concatenate them at compile time, like this:

string s = "This is a very long string ...\n"
   " and it keeps on going...";

In Java, the only way I know to do this is with concatenation:

String s = "This is a very long string ...\n" +
   " and it keeps on going...";

The question is, does this generate a single string at runtime, or does java actually concatenate at compile time also? The reason the question comes up is because of the following behavior:

String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // this prints true, because the compiler
// generates only one "abc" object
String s3 = "a";
s3 += "bc";
System.out.println(s1 == s3); // false
shauryachats
  • 9,975
  • 4
  • 35
  • 48
Dov
  • 8,000
  • 8
  • 46
  • 75
  • 1
    Yes it does, try setting your `String`s as constants using `static final` modifiers and `s1 == s3` will be true. Edit: Oh, you don't even have to do that.. – Bubletan Apr 15 '15 at 15:53
  • ouch! I will edit! Ok, On separate statements, the compiler does not optimize, which is how I am able to demonstrate to students that s1 != s3. But in a single statement, it is optimized. – Dov Apr 15 '15 at 15:54
  • 1
    Oh, come on. `s1==s3` is `true`! – Sid Zhang Apr 15 '15 at 15:54
  • 1
    Seems very similar to http://stackoverflow.com/questions/15427599/a-confusion-about-java-string-literal-pool-and-strings-concatenation and I think it provides the useful information you are looking for. – Erik Gillespie Apr 15 '15 at 15:55

2 Answers2

3
String s3 = "a";
s3 += "bc";

Is same as:

String s3 = "a";
s3 = new StringBuilder().append(s3).append("bc").toString();

So it creates a new instance of String.

You can even try:

String s = null;
s += null;
System.out.println(s); // prints "nullnull"
Bubletan
  • 3,833
  • 6
  • 25
  • 33
1

Java creates a single immutable object per string, but will reuse literals for performance gains.

This line creates an immutable string s1

String s1 = "abc"; 

Will reference the same string literal as s1 since this is a literal and can be optimized by the compiler.

String s2 = "abc"; 

This is an identity comparison, you are asking are S1 and S2 the same object, not the same string. Since the compiler has optimized by makeing the two objects reference the same immutable string this returns true.

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

This creates 2 immutable strings, then a third string is created at runtime. Since the runtimecant guarantee that it can find an already existing string to reference efficently it just creates a new object and create a new immutable string s3

String s3 = "a";
s3 = s3 + "bc";  

This is false, as they are two separate data objects.

 System.out.println(s1 == s3); 

Note String equality returns true, here is how we compare the contents of the string object, not the object location. That is the first comparison checks for identity, the second checks for equality.

 System.out.println(s1.equals(s3));

Java knows creating an Data object for every step of the string concatenation process is very ineffiecent. To help with the java hava the StringBuilder api which does more performent concats.

 String s = "a";
 s += "b";
 s += "c";
 s += "d";
 s += "e";

results in '9' string objects being created and written to memory ...

 ("a", "b", "ab", "c", "abc", "d", "abcd", "e", "abcde")

The string builder helps

StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b");
sb.append("c");
sb.append("d");
sb.append("e");

Is more effcient as it performs one single concat and results in better memory usage.

("a", "b", "c", "d", "e", "abcde")
gbtimmon
  • 4,238
  • 1
  • 21
  • 36
  • Minor nit: `s1==s2` is not object comparison, it's object _reference_ comparison. It checks equality of the reference pointing to an object, not the object itself. – Ryan J Apr 15 '15 at 15:59
  • If you'd actually run the code you posted, you'd see that your premise is incorrect. In your case `s1` **is** equal to `s3`. – JonK Apr 15 '15 at 16:00
  • You are missing the point, s3 is equal to s1 because it is in the literal pool. – Dov Apr 15 '15 at 16:00
  • `"a" + "bc"` is concatenated at compile time. It *doesn't* create two immutable strings. – JonK Apr 15 '15 at 16:05
  • @JonK Please see the minor edit. Its all about weather or not the compiler optimizes. – gbtimmon Apr 15 '15 at 16:07