1

Possible Duplicate:
Why does + work with Strings in Java?

The following statements are valid in Java.

int a=50;
String tmp="a = ";
String b=tmp+a;

b of type String now contains a = 50 (as a String).

Although tmp is of type String and a is of type int, the concatenation is made (even though Java doesn't support operator overloading).

One of the reasons why Java doesn't support operator overloading (as with other languages. In fact, I have no depth knowledge of any language).

Java does not support operator overloading. Operator overloading is sometimes a source of ambiguity in C++ program, and the Java design team felt that it causes more trouble than benefit.

More about it.

How is this statement String b=tmp+a; evaluated? There must be some equivalent concept of Operator Overloading internally.


Just one question : Can we see literally how it's implemented or we should just believe "It's just a feature of the language"?

I have heard that the Java compiler uses StringBuilder/StringBuffer (with the append() method) to achieve this but I'm not sure about that.

Community
  • 1
  • 1
Tiny
  • 27,221
  • 105
  • 339
  • 599
  • [+ operator for strings in Java](http://stackoverflow.com/q/2328483/471214) and [Why does + work with Strings in Java?](http://stackoverflow.com/q/5464330/471214) – mmdemirbas Jul 21 '12 at 16:14
  • It's just built into the compiler as a special case; it's nothing that could be generalized. – Louis Wasserman Jul 21 '12 at 18:32

3 Answers3

5

Technically this is just a different operator that happens to have the same symbol. It's the "string concatenation operator"; see section 15.18.1 of the Java Language Specification.

Regarding implementation, the JLS has this to say:

An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • `tmp+a`==`new StringBuilder().append(tmp).append(a).toString();`? As mentioned [here](http://stackoverflow.com/questions/2328483/operator-for-string-in-java). – Tiny Jul 21 '12 at 16:35
  • @Tiny: Yes, the JLS allows the implementation to do something like that (although I guess it would be more like `new StringBuilder(tmp).append(a.toString())`). – Oliver Charlesworth Jul 21 '12 at 16:37
2

Java doesn't allow user-defined operator overloading. The language specification gets to define whatever operators it wants :)

And yes, you can see how it's done internally - use javap -c to disassembly the class. For example, on my machine your code compiles to:

   0: bipush        50
   2: istore_1
   3: ldc           #2    // String a =
   5: astore_2
   6: new           #3    // class java/lang/StringBuilder
   9: dup
  10: invokespecial #4    // Method java/lang/StringBuilder."<init>":()V
  13: aload_2
  14: invokevirtual #5    // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  17: iload_1
  18: invokevirtual #6    // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  21: invokevirtual #7    // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  24: astore_3
  25: return

Some details are implementation-specific though; in particular, the Sun/Oracle compiler used to use StringBuffer, but now uses StringBuilder where available.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • `tmp+a`==`new StringBuilder().append(tmp).append(a).toString();`? As mentioned [here](http://stackoverflow.com/questions/2328483/operator-for-string-in-java). – Tiny Jul 21 '12 at 16:35
  • @Tiny: In this case, yes. But it doesn't have to be. It's implementation-specific. – Jon Skeet Jul 21 '12 at 18:47
  • See blog post here on the subject http://www.rationaljava.com/2015/02/the-optimum-method-to-concatenate.html – Dan Feb 17 '15 at 19:23
-1

Edit: Even the compiler doing this change (that I didn't know), using String concatenations is SLOWER then using StringBuilder. (Wrong => No, the compiler does not use StringBuilder/StringBuffer). You can test it just creating a simple benchmark. The + operator ir "overloaded" in Java for Strings, but the language does not support operator overload.

Try something like this to test the StringBuilder/StringBuffer thing:

String str = "";
StringBuffer sbf = new StringBuffer();
StringBuilder sb = new StringBuilder();

int nTests = 100;
int nConcats = 1000;

long initialTime = 0L;
long afterStrTime = 0L;
long afterSbfTime = 0L;
long afterSbTime = 0L;

for ( int i = 0; i < nTests; i++ ) {

    initialTime = System.currentTimeMillis();
    str = "";
    sbf = new StringBuffer();
    sb = new StringBuilder();

    for ( int j = 0; j < nConcats; j++ ) {
        str += "foo"; // or str = str + "foo"
    }
    afterStrTime = System.currentTimeMillis();

    for ( int j = 0; j < nConcats; j++ ) {
        sbf.append( "foo" );
    }
    afterSbfTime = System.currentTimeMillis();

    for ( int j = 0; j < nConcats; j++ ) {
        sb.append( "foo" );
    }
    afterSbTime = System.currentTimeMillis();

}

System.out.printf( "%d milliseconds to perform %d concatenations on String\n", afterStrTime - initialTime, nConcats );
System.out.printf( "%d milliseconds to perform %d concatenations on StringBuilder\n", afterSbfTime - afterStrTime, nConcats );
System.out.printf( "%d milliseconds to perform %d concatenations on StringBuffer\n",  afterSbTime - afterSbfTime, nConcats );

You will see that StringBuilder can be faster than StringBuffer, since it is not synchronized (StringBuffer is), and both are faster than String.

davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
  • 4
    You can test it by compiling the code given in the question and then running `javap -c` on it, which *clearly* shows it using `StringBuilder`. – Jon Skeet Jul 21 '12 at 16:13
  • @JonSkeet, ok, but can you explain why in my code above the String concatenations is not fast as StringBuffer one? If the compiler changes to StringBuffer, the execution should be equaly fast don't you agree? – davidbuzatto Jul 21 '12 at 16:26
  • 3
    Because it instantiates one StringBuilder for each iteration of the loop, and you only instantiate it once. – Didier L Jul 21 '12 at 16:30
  • So, even changing, it is slower. It is not the same to say that concatenating strings is the same to append in StringBuffer. – davidbuzatto Jul 21 '12 at 16:31
  • `tmp+a`==`new StringBuilder().append(tmp).append(a).toString();`? As mentioned [here](http://stackoverflow.com/questions/2328483/operator-for-string-in-java). – Tiny Jul 21 '12 at 16:35
  • @davidbuzatto: No-one claimed that concatenating strings *in a loop* would be the same as using `StringBuilder`/`StringBuffer`. It still has to produce a `String` object as the result of each iteration. But if you have a single expression with multiple concatenations in: `String a = x + "foo" + y + z;` that will generally use a single `StringBuilder`/`StringBuffer`. – Jon Skeet Jul 21 '12 at 18:49
  • @JonSkeet: Hi Jon. I know. I just tried to improve my answer to explain something for the OP and for the readers. I know that the answer was wrong. – davidbuzatto Jul 22 '12 at 03:10