36

String is a special case in Java. It's a class, which I can examine in the source code, but it also has its own infix operator +, which seems to be syntactic sugar for StringBuilder.

For example,

"Hello " + yourName;

could become

new StringBuilder().append("Hello ").append(yourName).toString();

There are no user-defined operators in Java, so where is + specified for String?

Could the same mechanism be used to make additional operators, such as for vectors?

sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
  • 6
    Where is `+` specified for `int`? – gronostaj Sep 22 '15 at 12:45
  • @gronostaj - `+` is recognised by the compiler as well. `int i= 2+3` will be replaced by `int i=5`. In case the value of int cannot be determined at compile time, then there are instructions like `iadd` which are used in place of `+` – TheLostMind Sep 22 '15 at 14:10
  • 7
    @TheLostMind I know. OP asked "*where is + specified for String?*", so I've tried to make him think why would the type matter. – gronostaj Sep 22 '15 at 14:43

4 Answers4

45

+ is implemented in java compilers. The compiler replaces String + String with either compile time constants or StringBuilder code. Note that this applies to primitives too. i.e, int i=1+2 could get directly replaced to int i=3 during compilation itself.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • 2
    Do you have a link to the compiler source where this happens? – sdgfsdh Sep 22 '15 at 10:13
  • 2
    @sdgfsdh - I could show you byte code . Would that suffice?. You will be able to see that `+` is NOT going as part of byte code – TheLostMind Sep 22 '15 at 10:13
  • I agree with the answer above and also want to add that '+' is not syntax sugar for StringBuilder. When you use StringBuilder it allows don't create many String objects. In case you use '+' every addition is a new String object. – jokernoel Sep 22 '15 at 10:14
  • i think that is the way binary is feeded into jvm. actual implementation has to be in native C of jvm's code. – aish Sep 22 '15 at 10:16
  • 3
    @aishu - No. JVM usually doesn't come into picture here. Compiler does this stuff – TheLostMind Sep 22 '15 at 10:17
  • 1
    Or with `StringBuffer` :) It varies as per compiler implementation. Upvote from my end. – Suresh Atta Sep 22 '15 at 10:21
  • @laune - edited my answer :) – TheLostMind Sep 22 '15 at 10:25
  • 6
    As you asked for a link to compiler source, [here's the Jikes compiler implementing `+` for Strings](http://jikes.cvs.sourceforge.net/viewvc/jikes/jikes/src/bytecode.cpp?revision=1.185&view=markup#l5946) – Stuart Caie Sep 22 '15 at 18:32
  • javac string concatenation. In `langtools\src\share\classes\com\sun\tools\javac\jvm\Gen.java` http://hg.openjdk.java.net/jdk8u/jdk8u60/langtools/file/d56703662c0f/src/share/classes/com/sun/tools/javac/jvm/Gen.java#l2112 – turbanoff Sep 23 '15 at 13:03
24

You can check with specification. The compiler have the implementation of it, not the Java source code.

Java Language Specification- 15.18.1. String Concatenation Operator +

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.

It shows the evidence that the implementation is depends on the compiler.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
5

While currently most of Java compilers using StringBuilder chain, it's not specified that it should be always in this way. In particular there's a proposal to change this drastically in Java-9 replacing with single invokedynamic call and introduce new metafactory which will generate an appropriate MethodHandle in runtime to perform concatenation.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • I wonder why Java doesn't static concatenation methods which take two, three, or four `String` instances, and also one that takes or else a `string[]`, and in any case returns a new string containing the concatenation of all the strings in question? Such functions could be in every case more efficient than code which actually uses `StringBuilder`. The only way I can see `StringBuilder` as being even remotely reasonable would be if most versions of the JIT peep-hole optimize certain usage patterns to invoke internal functions of the indicated form. – supercat Sep 22 '15 at 20:23
  • @supercat, are you looking for [`String.join("", String...)`](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#join-java.lang.CharSequence-java.lang.CharSequence...-)? Note that `StringBuilder` can accept not only strings, but primitive values like `int`, `double`, `boolean` and so on. And during String concatenation they are not boxed, nor separate strings are created: their values are concatenated directly into the buffer. How would you imagine to solve this by static methods? The number of possible combinations is too big. – Tagir Valeev Sep 23 '15 at 00:15
  • Was "join" a later edition? My Java lib source doesn't have it. Use of StringBuilder is guaranteed to generate an amount of garbage greater than the total length of the string created. For the scenario where all the things being concatenated were numbers, it might end up slightly ahead of `String.join(thing1.toString(), thing2.toString(), etc.)`, but not by much. – supercat Sep 23 '15 at 15:07
  • @supercat, String.join appeared in Java 8 and until Java 9 it internally uses the same StringBuilder. It's not guaranteed that StringBuilder will create any garbage. JIT-compiler is smart and can optimize some simple cases (like concatenation of String and int) directly creating the resulting char[] array of target size and the String instance (no garbage at all). Unfortunately it cannot optimize every string concatenation pattern, that's why "indify String concatenation" proposal is born. – Tagir Valeev Sep 23 '15 at 15:14
  • What's "indify"? I'm not clear why `String.join` would need to use `StringBuilder`, since it should be able to determine the sizes of all the constitutent items and attemtpt to populate the array, checking bounds as it goes along (to allow for the possibility of the `String[]` being changed underneath it). If there is a bounds-related problem, make a copy of all remaining `String` elements, recompute the required length, allocate it, and copy the rest. – supercat Sep 23 '15 at 16:15
  • The only time `String.join` would need any extra allocations would be in the unlikely scenario that code substitutes a different string in the passed-in array while it's running, and making a copy of the passed-in array once that happens would ensure clean behavior. Maybe the JIT could optimize `StringBuilder`, but performance numbers I've seen don't make it sound like it does. – supercat Sep 23 '15 at 16:17
2

As for the language, no, it's not extensible. This is specific behavior, no other class extends the + operator.

As for where this is done, search for string_add (not a real JVM op) in the following files:


As to why, Java was supposed to be simple, or at least simpler than C++, and a basic thing like string manipulation was kind of mandatory. However, operator overloading would add complexity.

acelent
  • 7,965
  • 21
  • 39