1

In Java an int can be converted into a String in to ways

String number = Integer.toString(6);

or

String number = 6 + "";

or

String number = String.valueOf(6);

Two use a function, and one is concatenation, but all achieve the same goal, Which is better to use? and which one is more efficient? Or do they all end up funneling to a single function? or does the compiler just end up swapping them out for the same function in the end?

DeadChex
  • 4,379
  • 1
  • 27
  • 34
  • 1
    Useless concatenation *might* be JITted away eventually, but ew. – Dave Newton Oct 01 '13 at 17:58
  • Unless you're doing a _lot_ of them in a loop, my opinion is it's most efficient just to use `String number = 6 + "";` as it looks cleaner and is shorter to type. Most likely it will have zero noticeable effect on execution. – Reinstate Monica -- notmaynard Oct 01 '13 at 18:03
  • `String.valueOf(int)` will call internally `Integer.toString` so "it is the same". The concatenation will end in 3 resources being built.. the 6, the "" and the result "6". While toString will build the string using chars and offset.. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java#Integer.toString%28int%29 – porfiriopartida Oct 01 '13 at 18:08
  • Even in a loop you are very likely to see no difference. But as long as both `""` and the number are constant like with `6+""` it is the most efficient solution as it is also a constant. It is even true that `(6+"") == "6"` – Holger Oct 01 '13 at 18:08
  • I think it depends on developer which approach will use. I cannot tell you why you shouldn't use concatenation. I usually use ` + ""` but when i know that i will have hard work with Strings since they are immutable i usually use StringBuilder. Approaches you mentioned in question have same result but looks differently. I think there is not rule that exactly says *"you shouldn't use concatenation"* Only thing i can say for sure is that approaches except concatenation are "cleaner". – Simon Dorociak Oct 01 '13 at 18:08
  • Well it may seems as duplicate but OP is asking about `6+""` so it is `int` literal, not `int` variable. In this case Java7 compiler will convert it to string in compilation type so it would be the same as writing `"6"` so it is the best option here. But in case if we would like to convert `int` variable like `String tmp=i+""` then compiler would change it to `String tmp = new StringBuilder(String.valueOf(i)).toString();` so simply calling `Integer.valueOf(i)` would be better since `String.valueOf(i))` uses it internally. – Pshemo Oct 01 '13 at 18:37

2 Answers2

4

String.valueOf calls Integer.toString: http://www.mavenjava.com/sun/jdk/1.6.0/src/java/lang/String.java.html#String.valueOf%28int%29

public static String valueOf(int i) { 
    return Integer.toString(i, 10); 
} 

String number = 6 + ""; uses a StringBuilder and appends:

String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.

(which is inherently slower than the other two ways). The best bet is to directly use Integer.toString

SheetJS
  • 22,470
  • 12
  • 65
  • 75
  • 3
    `6 + ""` is a compile time constant => no StringBuilder, just a hardcoded constant... – assylias Oct 01 '13 at 18:03
  • 2
    @assylias Strictly speaking, the spec does not require that simplification – SheetJS Oct 01 '13 at 18:04
  • Neither does it strictly require a StringBuilder. – UFL1138 Oct 01 '13 at 18:05
  • 1
    @UFL1138 The aforementioned quote is actually from the spec: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html – SheetJS Oct 01 '13 at 18:07
  • That is a fair point. – assylias Oct 01 '13 at 18:08
  • @Nirk I am aware that it may use StringBuilder and/or StringBuffer, but as has been pointed out, the compiler may optimize 6+"" into "6", in which case no SB is necessary. – UFL1138 Oct 01 '13 at 18:09
  • @UFL1138: The compiler *must* turn `6+""` into `"6"`. That’s part of the Java specification. The result is a *compile-time constant*. – Holger Oct 01 '13 at 18:12
  • http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 – Holger Oct 01 '13 at 18:14
  • It is interesting that there is no mentioning of StringBuilder or StringBuffer in the [String Class Javadocs of JDK 1.7](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html). – Edwin Dalorzo Oct 01 '13 at 18:26
  • @Edwin Dalorzo: I clearly see in that document: *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.* – Holger Oct 01 '13 at 19:01
-2

You should avoid String concatenation whenever you can, especially if it's in a loop. That said, a lot of times it's easiest code-wise to use ""+6. String.valueOf(6) is probably the best option. Under the hood concatenations get turned into a StringBuilder, so there's more overhead there than if you use String.valueOf(6). Integer.toString(6) is just weird IMO. Also if it's a literal you should just use "6".

UFL1138
  • 632
  • 3
  • 10
  • Why is it "just weird"? To me it seems more semantic. – Dave Newton Oct 01 '13 at 18:01
  • Do you have a reference about how string concatenation is implemented as StringBuilder under the hood? I'd love to read about that. – Edwin Dalorzo Oct 01 '13 at 18:01
  • @EdwinDalorzo There was a fair amount written about StringBuilder when it replaced StringBuffer; some searching should turn up enough info. – Dave Newton Oct 01 '13 at 18:01
  • @EdwinDalorzo it is the case - javac does it for you... – assylias Oct 01 '13 at 18:02
  • Have you ever used it instead of one of the other options? I certainly haven't. It's weird in one sense because toString usually takes no parameters. The other is that it's easy to confuse it with toString(int,int) that converts it to a given base instead of the default of 10. – UFL1138 Oct 01 '13 at 18:02
  • @EdwinDalorzo http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.18.1.2 – UFL1138 Oct 01 '13 at 18:04
  • Well, since concatenation is implemented at the language level and not at the API level, I have not found any reference like that in Javadocs, neither I remember that in JLS. Not even String.concat is implementat that way. So I am rather courious to read that reference. – Edwin Dalorzo Oct 01 '13 at 18:04
  • @UFL1138 I *always* use it instead of the other options, although in general I use templating instead. It's not easy to confuse it with a method that takes another parameter, and that there's a variant including the base makes it *more* semantic, not less. Plus you're converting an `int` (suspiciously close to `Integer`), and to me, the "value" of an integer *is* the integer, not a string. – Dave Newton Oct 01 '13 at 18:05
  • 1
    @EdwinDalorzo The *syntax* is implemented at the language level, the code that's *generated* can be whatever the Java compiler wants. – Dave Newton Oct 01 '13 at 18:06
  • @Dave Newton So, what you are saying is that if I decompile the code in the question I will see a StringBuffer instead of String being used? – Edwin Dalorzo Oct 01 '13 at 18:09
  • @EdwinDalorzo In many cases, yes. Did you know you can use `javap -c` to view the byte code? – UFL1138 Oct 01 '13 at 18:11
  • I guess my point here is that, according to the shared reference, there may be situations (not always) in which a Java compiler implementation may choose to do concatenation using StringBuilder. But I do not see that happening for the particular scenario of this questions and so, I think it cannot be categorically affirmed that it will be done with StringBuilder. We would need to discuss a particular JVM and compiler implementation to be sure of that. – Edwin Dalorzo Oct 01 '13 at 18:16
  • @Edwin Dalorzo: “ if I decompile the code in the question I will see a StringBuffer instead of String being used”? No. You will see that `6 + ""` has turned into `"6"` – Holger Oct 01 '13 at 18:17
  • @Holger The reference shared above says: "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" How can I verify that for this particular compiler using the example on the question this is what the compiler did? I can decompile the code and check, and if I do not see StringBuffer, then, does it mean it did not use it? Then the statement on the answer is wrong. – Edwin Dalorzo Oct 01 '13 at 18:20
  • @EdwinDalorzo No, I'm not saying that at all. I'm saying a compiler can generate whatever code it wants for string concatenation, including using a StringBuilder. In this case the compiler sees that it's just constants and doesn't need to use anything other than the already-converted constant. – Dave Newton Oct 01 '13 at 18:38
  • @Edwin Dalorzo: For the concatenation of compile-time constants the compiler *must* compute the result and create a compile-time constant. For all other concatenations involving variables (not containing a compile-time constant) the compiler *should* use a `StringBuilder`. But note that even variables might be a compile-time constant, e.g. `final int var=6;` – Holger Oct 01 '13 at 19:09