I am aware that String are immutable, and on when to use a StringBuilder or a StringBuffer. I also read that the bytecode for these two snippets would end up being the same:
//Snippet 1
String variable = "text";
this.class.getResourceAsStream("string"+variable);
//Snippet 2
StringBuilder sb = new StringBuilder("string");
sb.append("text");
this.class.getResourceAsStream(sb.toString());
But I obviously have something wrong. When debugging through Snippet 1 in eclipse, I am actually taken to the StringBuilder constructor and to the append method. I suppose I’m missing details on how bytecode is interpreted and how the debugger refers back to the lines in the source code; if anyone could explain this a bit, I’d really appreciate it. Also, maybe you can point out what’s JVM specific and what isn’t (I’m for example running Oracle’s v6), Thanks!
Because string concatenation (via the ‘+’ operator) is typically compiled to code that uses a
StringBufferorStringBuilderto do the concatenation. The JLS explicitly permits this behaviour.(If your code is using a
StringBufferrather than aStringBuilder, it is probably because it was compiled using a really old Java compiler, or because you have specified a really old target JVM. TheStringBuilderclass is a relatively addition to Java. Older versions of the JLS used to mentionStringBufferinstead ofStringBuilder, IIRC.)The bytecodes produced for
"string" + variable"depend on how the Java compiler handles the concatenation. (In fact, all generated bytecodes are Java compiler dependent to some degree. The JLS and JVM specs do not dictate what bytecodes must be generated. The specifications are more about how the program should behave, and what individual bytecodes do.)@supercat comments:
Maybe … but I’d say probably not. This is a complicated area involving complicated trade-offs. The chosen implementation strategy for string concatenation has to work well across a wide range of different use-cases.
My understanding is that the original strategy was chosen after looking at a number of approaches, and doing some large-scale static code analysis and benchmarking to try to figure out which approach was best. I imagine they considered all of the alternatives that you proposed. (After all, they were / are smart people …)
Having said that, the complete source code base for Java 6, 7 and 8 are available to you. That means that you could download it, and try some experiments of your own to see if your theories are right. If they are … and you can gather solid evidence that they are … then submit a patch to the OpenJDK team.