9

I saw this question a few minutes ago, and decided to take a look in the java String class to check if there was some overloading for the + operator.

I couldn't find anything, but I know I can do this

String ab = "ab";
String cd = "cd";
String both = ab + cd; //both = "abcd"

Where's that implemented?

Community
  • 1
  • 1
Samuel Carrijo
  • 17,449
  • 12
  • 49
  • 59

7 Answers7

14

From the Fine Manual:

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification.

See String Concatenation in the JLS.

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
9

The compiler treats your code as if you had written something like:

String both = new StringBuilder().append(ab).append(cd).toString();

Edit: Any reference? Well, if I compile and decompile the OP's code, I get this:

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

So, it's like I said.

Sean
  • 29,130
  • 4
  • 80
  • 105
5

Most of the answers here are correct (it's handled by the compiler, + is converted to .append()...)

I wanted to add that everyone should take a look at the source code for String and append at some point, it's pretty impressive.

I believe it came down to something like:

"a"+"b"+"c"

=

new StringBuilder().append("a").append("b").append("c")

But then some magic happens. This turns into:

  • Create a string array of length 3
  • copy a into the first position.
  • copy b into the second
  • copy c into the third

Whereas most people believe that it will create a 2 character array with "ab", and then throw it away when it creates a three character array with "abc". It actually understands that it's being chained and does some manipulation outside what you would assume if these were simple library calls.

There is also a trick where if you have the string "abc" and you ask for a substring that turns out to be "bc", they CAN share the exact same underlying array. You'll notice that there is a start position, end position and "shared" flag.

In fact, if it's not shared, it's possible for it to extend the length of a string array and copy the new characters in when appending.

Now I'm just being confusing. Read the source code--it's fairly cool.

Very Late Edit: The part about sharing the underlying array isn't quite true any more. They had to de-optimize String a little because people were downloading giant strings, taking a tiny sub-string and keeping it. This was holding the entire underlying array in storage, it couldn't be GC'd until all sub-references were dropped.

Bill K
  • 62,186
  • 18
  • 105
  • 157
  • 3
    There is no `new String().append("a").append("b").append("c")`, but `new StringBuilder().append("a").append("b).append("c").toString()`. The *no-stringbuilder* way would be `"a".concat("b").concat("c")`, and this is the inefficient way as you described. (But when using + with compile-time constants, all of this is already done by the compiler.) – Paŭlo Ebermann Jul 30 '13 at 16:15
2

It is handled by the compiler.

Fredrik
  • 5,759
  • 2
  • 26
  • 32
  • 1
    Impressive answer. Have you considered being a teacher? – whiskeysierra Feb 24 '10 at 20:35
  • @Willi Schönborn: Well, it is the simple and correct answer. I didn't have time to write more when I wrote it and when I got back to the computer there were plenty of answers explaining it in more detail. Sorry to say, but I don't see the point in duplicating the other answers, I recommend reading @Sean's and @jleedev's if you need more info (And yes, teaching is on my resume). – Fredrik Feb 24 '10 at 21:34
  • The point is: Your answer is so general, it fits for almost ~75% of all java related questions on SO. – whiskeysierra Feb 25 '10 at 18:45
  • @Will Schönborn 75% of all java issues are not handled by the compiler. In fact, in most cases the compiler just compiles source to byte code. The few exceptions are the + operator on String and a few things where the result is intrinsic function inlining. My answer got in first with the only intention to be a quick answer to point the OP in the right direction while waiting for more complete answers. I had like 30s to spare before a meeting and dedicated them to SO. If you don't like that, please go visit the hyphen site or something or build some rep yourself instead of complaining. – Fredrik Feb 25 '10 at 18:58
2

This is special behavior documented in the language specification.

15.18.1 String Concatenation Operator +

If only one operand expression is of type String, then string conversion is performed on the other operand to produce a string at run time. The result is a reference to a String object (newly created, unless the expression is a compile-time constant expression (§15.28))that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string. If an operand of type String is null, then the string "null" is used instead of that operand.

Otto Allmendinger
  • 27,448
  • 7
  • 68
  • 79
0

It's done at the language level. The Java Language Specification is very specific about what string addition must do.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
0

String is defined as a standard type just like int, double, float, etc. on compiler level. Essentially, all compilers have operator overloading. Operator overloading is not defined for Developers (unlike in C++).

Interestingly enough: This question was logged as a bug: http://bugs.sun.com/view_bug.do?bug_id=4905919

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228