A little StringBuilder drawback
Can you spot a mistake in the code below?
StringBuilder sb1 = new StringBuilder("0"); StringBuilder sb2 = new StringBuilder('1'); System.out.println(sb1.append(sb2).toString());
If you are attentive, you might spot it easily not even running the code.
I wasn't able to do it when I faced with such an issue a few weeks ago.
The result of the code above is really just a single zero and not
'1' are a string and a single character.
The first string builder
sb1 is constructed with an initial string
Whilst the second string builder
sb2 is constructed with some initial capacity.
Just because there are
StringBuilder constructor overloads, and one of them takes declares a single
'1' is a
char so it will be converted to
int silently initializing a
StringBuilder instance with capacity of
So here are the overloads used in the code:
My IntelliJ IDEA provides a nice set of inspections and intentions even for the Community Edition. One of this inspections, Replace String with Char, warns about passing a string to methods that also may accept characters. Fore example, the code below:
return new StringBuilder() .append("(") .append(value) .append(")") .toString();
can be refactored to slightly different code:
return new StringBuilder() .append('(') .append(value) .append(')') .toString();
I'm fine with such an intention since appending a single character is a bit faster than appending a string. However, the following code (padded parenthesis):
return new StringBuilder(" (") .append(value) .append(") ") .toString();
append right after the constructor.
Once shorter delimiters are fine, it might be refactored manually:
return new StringBuilder('(') .append(value) .append(')') .toString();
which does not work as it might be wanted to work. Fortunately, IntelliJ IDEA reports a warning for the constructor (not for me; at least they say it has to). Sometimes I think that it would be really great to have numerical types up-conversion explicit. Even if slightly more code is necessary.