<p>Assuming String a and b:</p>

<pre><code>a += b
a = a.concat(b)
</code></pre>

<p>Under the hood, are they the same thing?</p>

<p>Here is concat decompiled as reference. I'd like to be able to decompile the <code>+</code> operator as well to see what that does.</p>

<pre><code>public String concat(String s) {

    int i = s.length();
    if (i == 0) {
        return this;
    }
    else {
        char ac[] = new char[count + i];
        getChars(0, count, ac, 0);
        s.getChars(0, i, ac, count);
        return new String(0, count + i, ac);
    }
}
</code></pre>

[{'answer_id': 47615, 'author': 'Niyaz', 'author_id': 184, 'author_profile': 'https://Stackoverflow.com/users/184', 'pm_score': 2, 'selected': False, 'text': "<p>The <strong>+ operator</strong> can work between a string and a string, char, integer, double or float data type value. It just converts the value to its string representation before concatenation.</p>\n\n<p>The <strong>concat operator</strong> can only be done on and with strings. It checks for data type compatibility and throws an error, if they don't match.</p>\n\n<p>Except this, the code you provided does the same stuff.</p>\n"}, {'answer_id': 47624, 'author': 'Bartosz Bierkowski', 'author_id': 3666, 'author_profile': 'https://Stackoverflow.com/users/3666', 'pm_score': 2, 'selected': False, 'text': '<p>I don\'t think so.</p>\n\n<p><code>a.concat(b)</code> is implemented in String and I think the implementation didn\'t change much since early java machines. The <code>+</code> operation implementation depends on Java version and compiler. Currently <code>+</code> is implemented using <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html" rel="nofollow noreferrer"><code>StringBuffer</code></a> to make the operation as fast as possible. Maybe in the future, this will change. In earlier versions of java <code>+</code> operation on Strings was much slower as it produced intermediate results.</p>\n\n<p>I guess that <code>+=</code> is implemented using <code>+</code> and similarly optimized.</p>\n'}, {'answer_id': 47626, 'author': 'Eli Courtwright', 'author_id': 1694, 'author_profile': 'https://Stackoverflow.com/users/1694', 'pm_score': 7, 'selected': False, 'text': '<p><a href="https://stackoverflow.com/a/47615/662581">Niyaz</a> is correct, but it\'s also worth noting that the special + operator can be converted into something more efficient by the Java compiler.  Java has a StringBuilder class which represents a non-thread-safe, mutable String.  When performing a bunch of String concatenations, the Java compiler silently converts</p>\n\n<pre><code>String a = b + c + d;\n</code></pre>\n\n<p>into</p>\n\n<pre><code>String a = new StringBuilder(b).append(c).append(d).toString();\n</code></pre>\n\n<p>which for large strings is significantly more efficient.  As far as I know, this does not happen when you use the concat method.</p>\n\n<p>However, the concat method is more efficient when concatenating an empty String onto an existing String.  In this case, the JVM does not need to create a new String object and can simply return the existing one.  See <a href="http://java.sun.com/javase/6/docs/api/java/lang/String.html#concat(java.lang.String)" rel="noreferrer">the concat documentation</a> to confirm this.</p>\n\n<p>So if you\'re super-concerned about efficiency then you should use the concat method when concatenating possibly-empty Strings, and use + otherwise.  However, the performance difference should be negligible and you probably shouldn\'t ever worry about this.</p>\n'}, {'answer_id': 47628, 'author': 'Tom Hawtin - tackline', 'author_id': 4725, 'author_profile': 'https://Stackoverflow.com/users/4725', 'pm_score': 10, 'selected': True, 'text': '<p>No, not quite.</p>\n\n<p>Firstly, there\'s a slight difference in semantics. If <code>a</code> is <code>null</code>, then <code>a.concat(b)</code> throws a <code>NullPointerException</code> but <code>a+=b</code> will treat the original value of <code>a</code> as if it were <code>null</code>. Furthermore, the <code>concat()</code> method only accepts <code>String</code> values while the <code>+</code> operator will silently convert the argument to a String (using the <code>toString()</code> method for objects). So the <code>concat()</code> method is more strict in what it accepts.</p>\n\n<p>To look under the hood, write a simple class with <code>a += b;</code></p>\n\n<pre><code>public class Concat {\n    String cat(String a, String b) {\n        a += b;\n        return a;\n    }\n}\n</code></pre>\n\n<p>Now disassemble with <code>javap -c</code> (included in the Sun JDK). You should see a listing including:</p>\n\n<pre><code>java.lang.String cat(java.lang.String, java.lang.String);\n  Code:\n   0:   new     #2; //class java/lang/StringBuilder\n   3:   dup\n   4:   invokespecial   #3; //Method java/lang/StringBuilder."&lt;init&gt;":()V\n   7:   aload_1\n   8:   invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;\n   11:  aload_2\n   12:  invokevirtual   #4; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;\n   15:  invokevirtual   #5; //Method java/lang/StringBuilder.toString:()Ljava/lang/    String;\n   18:  astore_1\n   19:  aload_1\n   20:  areturn\n</code></pre>\n\n<p>So, <code>a += b</code> is the equivalent of</p>\n\n<pre><code>a = new StringBuilder()\n    .append(a)\n    .append(b)\n    .toString();\n</code></pre>\n\n<p>The <code>concat</code> method should be faster. However, with more strings the <code>StringBuilder</code> method wins, at least in terms of performance.</p>\n\n<p>The source code of <code>String</code> and <code>StringBuilder</code> (and its package-private base class) is available in src.zip of the Sun JDK. You can see that you are building up a char array (resizing as necessary) and then throwing it away when you create the final <code>String</code>. In practice memory allocation is surprisingly fast.</p>\n\n<p><strong>Update:</strong> As Pawel Adamski notes, performance has changed in more recent HotSpot. <code>javac</code> still produces exactly the same code, but the bytecode compiler cheats. Simple testing entirely fails because the entire body of code is thrown away. Summing <code>System.identityHashCode</code> (not <code>String.hashCode</code>) shows the <code>StringBuffer</code> code has a slight advantage. Subject to change when the next update is released, or if you use a different JVM. From <a href="https://twitter.com/lukaseder" rel="noreferrer">@lukaseder</a>, <a href="https://gist.github.com/apangin/7a9b7062a4bd0cd41fcc" rel="noreferrer">a list of HotSpot JVM intrinsics</a>.</p>\n'}, {'answer_id': 47694, 'author': 'Marcio Aguiar', 'author_id': 4213, 'author_profile': 'https://Stackoverflow.com/users/4213', 'pm_score': 4, 'selected': False, 'text': '<p>How about some simple testing? Used the code below:</p>\n\n<pre><code>long start = System.currentTimeMillis();\n\nString a = "a";\n\nString b = "b";\n\nfor (int i = 0; i &lt; 10000000; i++) { //ten million times\n     String c = a.concat(b);\n}\n\nlong end = System.currentTimeMillis();\n\nSystem.out.println(end - start);\n</code></pre>\n\n<ul>\n<li>The <code>"a + b"</code> version executed in <strong>2500ms</strong>.</li>\n<li>The <code>a.concat(b)</code> executed in <strong>1200ms</strong>.</li>\n</ul>\n\n<p>Tested several times. The <code>concat()</code> version execution took half of the time on average.</p>\n\n<p>This result surprised me because the <code>concat()</code> method always creates a new string (it returns a "<code>new String(result)</code>". It\'s well known that:</p>\n\n<pre><code>String a = new String("a") // more than 20 times slower than String a = "a"\n</code></pre>\n\n<p>Why wasn\'t the compiler capable of optimize the string creation in "a + b" code, knowing the it always resulted in the same string? It could avoid a new string creation.\nIf you don\'t believe the statement above, test for your self. </p>\n'}, {'answer_id': 47716, 'author': 'Jason Cohen', 'author_id': 4926, 'author_profile': 'https://Stackoverflow.com/users/4926', 'pm_score': 5, 'selected': False, 'text': '<p>Tom is correct in describing exactly what the + operator does.  It creates a temporary <code>StringBuilder</code>, appends the parts, and finishes with <code>toString()</code>.</p>\n\n<p>However, all of the answers so far are ignoring the effects of HotSpot runtime optimizations.  Specifically, these temporary operations are recognized as a common pattern and are replaced with more efficient machine code at run-time.</p>\n\n<p>@marcio: You\'ve created a <a href="http://www.ibm.com/developerworks/java/library/j-jtp02225.html" rel="noreferrer">micro-benchmark</a>; with modern JVM\'s this is not a valid way to profile code.</p>\n\n<p>The reason run-time optimization matters is that many of these differences in code -- even including object-creation -- are completely different once HotSpot gets going.  The only way to know for sure is profiling your code <i>in situ</i>.</p>\n\n<p>Finally, all of these methods are in fact incredibly fast.  This might be a case of premature optimization.  If you have code that concatenates strings a lot, the way to get maximum speed probably has nothing to do with which operators you choose and instead the algorithm you\'re using!</p>\n'}, {'answer_id': 47758, 'author': 'ckpwong', 'author_id': 2551, 'author_profile': 'https://Stackoverflow.com/users/2551', 'pm_score': 6, 'selected': False, 'text': "<p>I ran a similar test as @marcio but with the following loop instead:</p>\n\n<pre><code>String c = a;\nfor (long i = 0; i &lt; 100000L; i++) {\n    c = c.concat(b); // make sure javac cannot skip the loop\n    // using c += b for the alternative\n}\n</code></pre>\n\n<p>Just for good measure, I threw in <code>StringBuilder.append()</code> as well.  Each test was run 10 times, with 100k reps for each run.  Here are the results:</p>\n\n<ul>\n<li><code>StringBuilder</code> wins hands down.  The clock time result was 0 for most the runs, and the longest took 16ms.</li>\n<li><code>a += b</code> takes about 40000ms (40s) for each run.</li>\n<li><code>concat</code> only requires 10000ms (10s) per run.</li>\n</ul>\n\n<p>I haven't decompiled the class to see the internals or run it through profiler yet, but I suspect <code>a += b</code> spends much of the time creating new objects of <code>StringBuilder</code> and then converting them back to <code>String</code>.</p>\n"}, {'answer_id': 25378169, 'author': 'Deepak Sharma', 'author_id': 1047565, 'author_profile': 'https://Stackoverflow.com/users/1047565', 'pm_score': 3, 'selected': False, 'text': '<p>Basically, there are two important differences between + and the <code>concat</code> method.</p>\n\n<ol>\n<li><p>If you are using the <strong>concat</strong> method then you would only be able to concatenate strings while in case of the <strong>+</strong> operator, you can also concatenate the string with any data type.</p>\n\n<p><strong>For Example:</strong></p>\n\n<pre><code>String s = 10 + "Hello";\n</code></pre>\n\n<p>In this case, the output should be <strong>10Hello</strong>.</p>\n\n<pre><code>String s = "I";\nString s1 = s.concat("am").concat("good").concat("boy");\nSystem.out.println(s1);\n</code></pre>\n\n<p>In the above case you have to provide two strings mandatory.</p></li>\n<li><p>The second and main difference between <strong>+</strong> and <strong>concat</strong> is that:</p>\n\n<p><strong>Case 1:</strong>\nSuppose I concat the same strings with <strong>concat</strong> operator in this way</p>\n\n<pre><code>String s="I";\nString s1=s.concat("am").concat("good").concat("boy");\nSystem.out.println(s1);\n</code></pre>\n\n<p>In this case total number of objects created in the pool are 7 like this:</p>\n\n<pre><code>I\nam\ngood\nboy\nIam\nIamgood\nIamgoodboy\n</code></pre>\n\n<p><strong>Case 2:</strong></p>\n\n<p>Now I am going to concatinate the same strings via <strong>+</strong> operator</p>\n\n<pre><code>String s="I"+"am"+"good"+"boy";\nSystem.out.println(s);\n</code></pre>\n\n<p>In the above case total number of objects created are only 5.</p>\n\n<p>Actually when we concatinate the strings via <strong>+</strong> operator then it maintains a StringBuffer class to perform the same task as follows:-</p>\n\n<pre><code>StringBuffer sb = new StringBuffer("I");\nsb.append("am");\nsb.append("good");\nsb.append("boy");\nSystem.out.println(sb);\n</code></pre>\n\n<p>In this way it will create only five objects.</p></li>\n</ol>\n\n<p>So guys these are the basic differences between <strong>+</strong> and the <strong>concat</strong> method.\nEnjoy :)</p>\n'}, {'answer_id': 28428596, 'author': 'iamreza', 'author_id': 4537488, 'author_profile': 'https://Stackoverflow.com/users/4537488', 'pm_score': 1, 'selected': False, 'text': "<p>When using +, the speed decreases as the string's length increases, but when using concat, the speed is more stable, and the best option is using the StringBuilder class which has stable speed in order to do that.</p>\n\n<p>I guess you can understand why. But the totally best way for creating long strings is using StringBuilder() and append(), either speed will be unacceptable.</p>\n"}, {'answer_id': 43030370, 'author': 'dingalapadum', 'author_id': 2995907, 'author_profile': 'https://Stackoverflow.com/users/2995907', 'pm_score': 3, 'selected': False, 'text': '<p>For the sake of completeness, I wanted to add that the definition of the \'+\' operator can be found in the <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1" rel="nofollow noreferrer">JLS SE8 15.18.1</a>:</p>\n<blockquote>\n<p><em>If only one operand expression is of type String, then string\nconversion (§5.1.11) is performed on the other operand to produce a\nstring at run time.</em></p>\n<p><em>The result of string concatenation is a reference to a String object\nthat is the concatenation of the two operand strings. The characters\nof the left-hand operand precede the characters of the right-hand\noperand in the newly created string.</em></p>\n<p><em>The String object is newly created (§12.5) unless the expression is a\nconstant expression (§15.28)</em></p>\n</blockquote>\n<p>About the implementation the JLS says the following:</p>\n<blockquote>\n<p><em>An implementation may choose to perform conversion and concatenation\nin one step to avoid creating and then discarding an intermediate\nString object. To increase the performance of repeated string\nconcatenation, a Java compiler may use the StringBuffer class or a\nsimilar technique to reduce the number of intermediate String objects\nthat are created by evaluation of an expression.</em></p>\n<p><em>For primitive types, an implementation may also optimize away the\ncreation of a wrapper object by converting directly from a primitive\ntype to a string.</em></p>\n</blockquote>\n<p>So judging from the \'a Java compiler may use the StringBuffer class or a similar technique to reduce\', different compilers could produce different byte-code.</p>\n'}, {'answer_id': 46485284, 'author': 'Paweł Adamski', 'author_id': 1268294, 'author_profile': 'https://Stackoverflow.com/users/1268294', 'pm_score': 5, 'selected': False, 'text': '<p>Most answers here are from 2008. It looks that things have changed over the time.  My latest benchmarks made with JMH shows that on Java 8 <code>+</code> is around two times faster than <code>concat</code>. </p>\n\n<p>My benchmark:</p>\n\n<pre><code>@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)\n@Measurement(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)\npublic class StringConcatenation {\n\n    @org.openjdk.jmh.annotations.State(Scope.Thread)\n    public static class State2 {\n        public String a = "abc";\n        public String b = "xyz";\n    }\n\n    @org.openjdk.jmh.annotations.State(Scope.Thread)\n    public static class State3 {\n        public String a = "abc";\n        public String b = "xyz";\n        public String c = "123";\n    }\n\n\n    @org.openjdk.jmh.annotations.State(Scope.Thread)\n    public static class State4 {\n        public String a = "abc";\n        public String b = "xyz";\n        public String c = "123";\n        public String d = "!@#";\n    }\n\n    @Benchmark\n    public void plus_2(State2 state, Blackhole blackhole) {\n        blackhole.consume(state.a+state.b);\n    }\n\n    @Benchmark\n    public void plus_3(State3 state, Blackhole blackhole) {\n        blackhole.consume(state.a+state.b+state.c);\n    }\n\n    @Benchmark\n    public void plus_4(State4 state, Blackhole blackhole) {\n        blackhole.consume(state.a+state.b+state.c+state.d);\n    }\n\n    @Benchmark\n    public void stringbuilder_2(State2 state, Blackhole blackhole) {\n        blackhole.consume(new StringBuilder().append(state.a).append(state.b).toString());\n    }\n\n    @Benchmark\n    public void stringbuilder_3(State3 state, Blackhole blackhole) {\n        blackhole.consume(new StringBuilder().append(state.a).append(state.b).append(state.c).toString());\n    }\n\n    @Benchmark\n    public void stringbuilder_4(State4 state, Blackhole blackhole) {\n        blackhole.consume(new StringBuilder().append(state.a).append(state.b).append(state.c).append(state.d).toString());\n    }\n\n    @Benchmark\n    public void concat_2(State2 state, Blackhole blackhole) {\n        blackhole.consume(state.a.concat(state.b));\n    }\n\n    @Benchmark\n    public void concat_3(State3 state, Blackhole blackhole) {\n        blackhole.consume(state.a.concat(state.b.concat(state.c)));\n    }\n\n\n    @Benchmark\n    public void concat_4(State4 state, Blackhole blackhole) {\n        blackhole.consume(state.a.concat(state.b.concat(state.c.concat(state.d))));\n    }\n}\n</code></pre>\n\n<p>Results:</p>\n\n<pre><code>Benchmark                             Mode  Cnt         Score         Error  Units\nStringConcatenation.concat_2         thrpt   50  24908871.258 ± 1011269.986  ops/s\nStringConcatenation.concat_3         thrpt   50  14228193.918 ±  466892.616  ops/s\nStringConcatenation.concat_4         thrpt   50   9845069.776 ±  350532.591  ops/s\nStringConcatenation.plus_2           thrpt   50  38999662.292 ± 8107397.316  ops/s\nStringConcatenation.plus_3           thrpt   50  34985722.222 ± 5442660.250  ops/s\nStringConcatenation.plus_4           thrpt   50  31910376.337 ± 2861001.162  ops/s\nStringConcatenation.stringbuilder_2  thrpt   50  40472888.230 ± 9011210.632  ops/s\nStringConcatenation.stringbuilder_3  thrpt   50  33902151.616 ± 5449026.680  ops/s\nStringConcatenation.stringbuilder_4  thrpt   50  29220479.267 ± 3435315.681  ops/s\n</code></pre>\n'}, {'answer_id': 70535824, 'author': 'Christian Meyer', 'author_id': 5759656, 'author_profile': 'https://Stackoverflow.com/users/5759656', 'pm_score': 0, 'selected': False, 'text': "<p>Note that <code>s.concat(&quot;hello&quot;);</code> would result in a <code>NullPointereException</code> when s is null. In Java, the behavior of the + operator is usually determined by the left operand:</p>\n<p><code>System.out.println(3 + 'a'); //100</code></p>\n<p>However, Strings are an exception. If either operand is a String, the result is expected to be a String. This is the reason null is converted into &quot;null&quot;, even though you might expect a <code>RuntimeException</code>.</p>\n"}]
['https://Stackoverflow.com/questions/47605', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/292/']