public String concatenationDemo1()
{
String value = "literal1" + " " + "literal2" + " " + STRING_CONSTANT;
return value;
}
The value that ends up in the compiled bytecode is
"literal1 literal2 constant". This is exactly what syntactic sugar is meant for!
public String concatenationDemo2()
{
String value = "literal1";
value += " ";
value += "literal2";
value += " ";
value += STRING_CONSTANT;
return value;
}
Each use of the
+= operator is converted into that three-step sequence of operations mentioned above! The resulting bytecode will construct
four instances of
StringBuilder, append a single string value to each of them, and call
toString() on the result. That's a bit of a waste. You'd be much better off constructing your own, single instance of
StringBuilder and calling
append() on it four times.
public String concatenationDemo3()
{
String value = createRandomString()
+ ' '
+ createRandomString()
+ ' '
+ STRING_CONSTANT;
return value;
}
public String concatenationDemo4a()
{
String value = new StringBuilder(String.valueOf(createRandomString()))
.append(' ')
.append(createRandomString())
.append(' ')
.append(STRING_CONSTANT).toString();
return value;
}
I have two asides to note here. It's probably more efficient to use
append(' ') over
append(" "), since the latter method has to iterate over a string value, adding each of its characters, while the former method only has to add a single character. As for that
concatenationDemo4a() method, I've never been a huge fan of that style of programming, where a method on an object returns
this so calls on that object can be chained. To my eye, this version looks better:
public String concatenationDemo4b()
{
StringBuilder value = new StringBuilder();
value.append(createRandomString());
value.append(' ');
value.append(createRandomString());
value.append(' ');
value.append(STRING_CONSTANT);
return value.toString();
}
This produces slightly longer bytecode, when compiled, though, so this is a classic tradeoff of readability versus efficiency (and, if you read my previous article, it may not make a difference anyway).
public String concatenationDemo5()
{
String value = "";
for (int i = 0; i < ITERATIONS; i++)
{
value += createRandomString();
}
return value;
}
This method is going to do that three-step sequence of operations
for each iteration of the loop. If
ITERATIONS equals
1000, that means this code will be creating 1,000 short-lived
StringBuilder objects, then calling
append() and
toString() on each of them. The code would be much better off if it looked like this:
public String concatenationDemo6()
{
StringBuilder value = new StringBuilder();
for (int i = 0; i < ITERATIONS; i++)
{
value.append(createRandomString());
}
return value.toString();
}
This way, there's one
StringBuilder instance per call to the method, saving plenty of processing power and memory overhead. (Where, by the way, would you find code that builds a string by looping and concatenating? It typically happens when reading text from a stream, like from a file or over a network.)
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)