Why does StringBuilders appear when debugging String concatenation?

I know that String is immutable and when to use StringBuilder or StringBuffer. I also read that the bytecode for these two fragments will be 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 actually get passed to the StringBuilder constructor and to the append method. I believe that I lack information on how the bytecode is interpreted and how the debugger refers to lines in the source code; if anyone could explain this, I would really appreciate it. In addition, perhaps you can indicate what the JVM is and what is not (for example, I am running Oracle v6), thanks!

+4
source share
2 answers

Why do StringBuilders appear when debugging string concatenation?

Since string concatenation (using the + operator) is usually compiled into code that uses a StringBuffer or StringBuilder to perform concatenation. JLS explicitly allows this behavior.

โ€œAn implementation can choose to perform conversion and concatenation in one step to avoid creating and then discarding the String intermediate object. To increase the performance of re-concatenating strings, the Java compiler can use the StringBuffer class or a similar technique to reduce the number of String intermediate objects created when evaluating the expressionโ€ . JLS 15.18.1 .

(If your code uses a StringBuffer rather than a StringBuilder , this is probably because it was compiled using a really old Java compiler or because you specified a really old target JVM. The StringBuilder class is a relatively addition to Java. In older versions JLS mentioned StringBuffer instead of StringBuilder , IIRC.)


In addition, perhaps you can indicate what the JVM is and what is not.

The bytecodes created for "string" + variable" depend on how the Java compiler handles concatenation. (In fact, all generated bytecodes are dependent on the Java compiler. The JLS and JVM specifications do not determine which bytecodes should The specs are more about how the program should behave and what individual byte codes do.)


Comments by @supercat:

I wonder why string concatenation will not be used, for example. overloading the constructor of a String that takes two String objects, allocates a buffer with the corresponding merged size and concatenates them? Or, when more lines are joined, an overload that takes a string []? Creating a String [] containing links to concatenated strings should be no more expensive than creating a StringBuilder, and the ability to create an ideal size backup storage in one shot should be an easy win for performance.

Maybe ... but I would probably say no. This is a complex area involving complex compromises. The chosen implementation strategy for string concatenation should work well in a wide range of different use cases.

I understand that the initial strategy was chosen after considering a number of approaches and conducting large-scale static code analysis and benchmarking in order to try to figure out which approach is best. I think they considered all the alternatives you proposed. (After all, they were smart people ...)

Having said that, a complete source code base for Java 6, 7 and 8 is available to you. This means that you can download it and try your own experiments to find out if your theories are correct. If they ... and you can gather strong evidence that they ... then send the patch to the OpenJDK team.

+8
source

@StephenC I'm still not convinced of the explanation. The compiler can do whatever optimization it wants to do, but when you debug through eclipse, the source code is hidden from the compiler code, and it should not skip one section of code to another code in the same source file.

The following description in the question assumes that the source code and byte code are not synchronized. that is, it does not run the last code.

When debugging through Snippet 1 in eclipse, I am actually taken to the StringBuffer constructor and to the append method

and how the debugger refers back to the lines in the source code

+1
source

All Articles