If there are lot of concatenations- Use StringBuffer. For one or two concatenations I dont think StringBuffer is required. For every concatenation creates one new string in the String pool.
May be you can consider StringBuilder if are not concerned about Thread safe operations.
When I compile that, then decompile that using JAD I get this:
You'll see two things:
1) the variable names are changed. That's because local variables are not stored in the compiled byte code.
2) the += is indeed replaced by the creation of a new empty StringBuilder, to which then both Strings are appended, after which it's toString() method is called.
Now about whether or not using a StringBuilder is more efficient, it depends:
1) if you only append two constants or literals, using + is more efficient. For instance, if I write "Hello " + "Everybody", the compiler will use String literal "Hello Everybody". The same holds for final variables for which the value can already be known by the compiler.
2) if you append only two Strings, String's concat method is actually preferred, because you don't create the intermediate StringBuilder but immediately create a String with the contents of the two source Strings.
3) if you only have one statement that creates the String, using + is perfectly fine. The compiler may change the code to use something even better in the future.
4) if you add to the Strings conditionally (with an if) or in a loop, an explicit StringBuilder is usually the best choice.
One final word on efficiency: if the StringBuilder's capacity needs to be increased a lot, it may loose a lot of its efficiency. If possible, specify the expected total capacity when creating it: new StringBuilder(expectedCapacity).
By the way, you don't see concat a lot. That's because using + is still easier to write, and it also automatically handles type conversion from anything to String. I can't remember ever having used concat.