You can also use the proper tool: Integer.toString(int): this might be easier to read as it clearly show your intent on getting a String out of your int.
int privacyLevel = 0;
builder.addFormDataPart("privacy", Integer.toString(privacyLevel));
When you use:
builder.addFormDataPart("privacy", "" + privacyLevel);
You are creating a new String from "" and Integer.toString(privacyLevel), but there might be some optimization during compile time or at runtime:
- Compiler can detect the
"" and directly use Integer.toString(privacyLevel).
- Compiler may replace the
+ operation by the String::concat method. Said method may return the other String when itself is empty, or return itself when the other String is empty (in openjdk 8u232, the method is actually checking the length of other and always perform a concatenation).
Now, to see what the compiler does, here is a simple code which does nothing extraordinary:
class Foobar {
public static void main(String[] args) {
int n = 1;
String s = n + "";
}
}
If you call javap -p Foobar.class, you can see what the compiler did (with Java 11.0.6, Java 8 use a StringBuilder):
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=3, args_size=1
0: iconst_1
1: istore_1
2: iload_1
3: invokedynamic #2, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String;
8: astore_2
9: return
LineNumberTable:
line 8: 0
line 9: 2
line 10: 9
Using Integer.toString only change the invokedynamic to invokestatic:
3: invokestatic #2 // Method java/lang/Integer.toString:(I)Ljava/lang/String
The compiler does not try to be intelligent in this case and don't optimize "" + int.
If you read Javadoc of java.lang.invoke.StringConcatFactory.makeConcatWithConstants(Lookup, String, MethodType, String, Object...), it references JLS 15.18.1 and JLS 5.1.11.
The JLS 15.18.1 explains the concatenation operation from String + Not a String:
If only one operand expression is of type String, then string
conversion (§5.1.11) is performed on the other operand to produce a
string at run time.
The JLS 5.1.11 explains how to convert an int to String:
A value x of primitive type T is first converted to a reference value
as if by giving it as an argument to an appropriate class instance
creation expression (§15.9):
If T is byte, short, or int, then use new Integer(x).
To answer your question:
I found this to be an unusual way of converting an int to string. And all the research
I've done pointed me to traditional methods of conversion.
So does anyone have an explanation for this? And is this even a "good practice"?
What's unusual in your case if the fact the String is after the number, rather than before (as in "privacyLevel: " + privacyLevel), but that is not strange given the JLS 15.18.1.
I could not say it is a good practice, even though it is relative, but I'd say it is legacy practice born for the fact that Integer.toString is not so old (I can't remember if it was added in Java 5 or 6) and that the easier way was to doing n + "" or "" + n.
I would personally favor Integer.toString because I find n + "" rather ugly. It might also be better in terms of performance due to the complexity of the conversion done otherwise. Luckily for you or my answer, someone did a JMH benchmark.
Last but not least, if you stick with concatenation, the result will depends on the version of compiler which will do the actual transformation:
- You are using Android Studio, and what apply to vanilla Java may not completely apply here.
- Java 8 use a
StringBuilder to generate an int' String.
- Java 11 use
invokedynamic and a lot of stuff harder (for me) to explain, but I assume it does its job and perform as well, if better, than StringBuilder.
Integer.toString seems to be optimized in newer hotspot JVM (it is annotated @HotSpotIntrinsicCandidate in Java 13).
System.out.println("My age is: " + age);?