String valueOf vs concatenation with empty string

Java

Java Problem Overview


I am working in Java code optimization. I'm unclear about the difference between String.valueOf or the +"" sign:

int intVar = 1;
String strVar = intVar + "";
String strVar = String.valueOf(intVar);

What is the difference between line 2 and 3?

Java Solutions


Solution 1 - Java

public void foo(){
int intVar = 5;
String strVar = intVar+"";    
}

This approach uses StringBuilder to create resultant String

public void foo();
  Code:
   0:   iconst_5
   1:   istore_1
   2:   new     #2; //class java/lang/StringBuilder
   5:   dup
   6:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   9:   iload_1
   10:  invokevirtual   #4; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
   13:  ldc     #5; //String
   15:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
   18:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
   21:  astore_2
   22:  return

public void bar(){
int intVar = 5;
String strVar = String.valueOf(intVar);
}

This approach invokes simply a static method of String to get the String version of int

public void bar();
  Code:
   0:   iconst_5
   1:   istore_1
   2:   iload_1
   3:   invokestatic    #8; //Method java/lang/String.valueOf:(I)Ljava/lang/Stri
ng;
   6:   astore_2
   7:   return

which in turn calls Integer.toString()

Solution 2 - Java

Ask yourself the purpose of the code. Is it to:

  • Concatenate an empty string with a value
  • Convert a value to a string

It sounds much more like the latter to me... which is why I'd use String.valueOf. Whenever you can make your code read in the same way as you'd describe what you want to achieve, that's a good thing.

Note that this works for all types, and will return "null" when passed a null reference rather than throwing a NullPointerException. If you're using a class (not an int as in this example) and you want it to throw an exception if it's null (e.g. because that represents a bug), call toString on the reference instead.

Solution 3 - Java

Using String.valueOf(int), or better, Integer.toString(int) is relatively more efficient for the machine. However, unless performance is critical (in which case I wouldn't suggest you use either) Then ""+ x is much more efficient use of your time. IMHO, this is usually more important. Sometimes massively more important.

In other words, ""+ wastes an object, but Integer.toString() creates several anyway. Either your time is more important or you want to avoid creating objects at all costs. You are highly unlikely to be in the position that creating several objects is fine, but creating one more is not.

Solution 4 - Java

I'd prefer valueOf(), because I think it's more readable and explicit.

Any concerns about performance are micro-optimizations that wouldn't be measurable. I wouldn't worry about them until I could take a measurement and see that they made a difference.

Solution 5 - Java

The first line is equivalent to

String strVal = String.valueOf(intVar) + "";

so that there is some extra (and pointless) work to do. Not sure if the compiler optimizes away concatenations with empty string literals. If it does not (and looking at @Jigar's answer it apparently does not), this will in turn become

String strVal = new StringBuilder().append(String.valueOf(intVar))
                      .append("").toString();

So you should really be using String.valueOf directly.

Solution 6 - Java

Well, if you look into the JRE source code, Integer.getChars(...) is the most vital method which actually does the conversion from integer to char[], but it's a package-private method.
So the question is how to get this method called with minimum overhead.
Following is an overview of the 3 approaches by tracing the calls to our target method, please look into the JRE source code to understand this better.

  1. "" + intVar compiles to :
    new StringBuilder() => StringBuilder.append(int) => Integer.getChars(...)
  2. String.valueOf(intVar) => Integer.toString(intVar) => Integer.getChars(...)
  3. Integer.toString(intVar) => Integer.getChars(...)

The first method unnecessarily creates one extra object i.e. the StringBuilder.
The second simply delegates to third method.
So you have the answer now.

PS: Various compile time and runtime optimizations come into play here. So actual performance benchmarks may say something else depending on different JVM implementations which we can't predict, so I generally prefer the approach which looks efficient by looking at the source code.

Solution 7 - Java

From the point of optimization , I will always prefer the String.valueOf() between the two. The first one is just a hack , trying to trick the conversion of the intVar into a String because the + operator.

Solution 8 - Java

Even though answers here are correct in general, there's one point that is not mentioned.

"" + intVar has better performance compared to String.valueOf() or Integer.toString(). So, if performance is critical, it's better to use empty string concatenation.

See this talk by Aleksey Shipilëv. Or these slides of the same talk (slide #24)

Solution 9 - Java

Concatenating Strings and other variables actually uses String.valueOf() (and StringBuilder) underneath, so the compiler will hopefully discard the empty String and produce the same bytecodes in both cases.

Solution 10 - Java

String strVar1 = intVar+"";
String strVar2 = String.valueOf(intVar);

strVar1 is equvalent to strVar2, but using int+emptyString "" is not elegant way to do it.

using valueOf is more effective.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCool Java guy מוחמדView Question on Stackoverflow
Solution 1 - JavajmjView Answer on Stackoverflow
Solution 2 - JavaJon SkeetView Answer on Stackoverflow
Solution 3 - JavaPeter LawreyView Answer on Stackoverflow
Solution 4 - JavaduffymoView Answer on Stackoverflow
Solution 5 - JavaThiloView Answer on Stackoverflow
Solution 6 - JavaJitesh SinghView Answer on Stackoverflow
Solution 7 - JavaBhaskarView Answer on Stackoverflow
Solution 8 - Javaesin88View Answer on Stackoverflow
Solution 9 - JavaMichael BorgwardtView Answer on Stackoverflow
Solution 10 - JavaRacooonView Answer on Stackoverflow