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?

3
  • 6
    Where is + specified for int? Commented Sep 22, 2015 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 + Commented Sep 22, 2015 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. Commented Sep 22, 2015 at 14:43

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Do you have a link to the compiler source where this happens?
@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
@aishu - No. JVM usually doesn't come into picture here. Compiler does this stuff
Or with StringBuffer :) It varies as per compiler implementation. Upvote from my end.
As you asked for a link to compiler source, here's the Jikes compiler implementing + for Strings
|
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.

1 Comment

Yes. java compiler may use.. But most compilers do. :)
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.

6 Comments

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, are you looking for String.join("", String...)? 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.
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, 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.
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.
|
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.