When I do ""+1 I get a String - Why
Please understand firstly that I fully understand that Java开发者_运维知识库 will return a String when I use ""+int.
What I'm really not sure about is what exactly is happening down at the memory aspect. How exactly is java performing this conversion. I mean this in a very indepth way, not 'auto boxing' or anything like that :)
I'm hoping someone with a deeper understanding can explain what exactly is done.
Actually, for "" + 1 the compiler creates a String constant String with the value of "1" and puts it into the constant pool - so nothing is done at runtime.
If you have "" + x (where x is an int variable) you get the following bytecode (from the current JDK 1.6):
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: ldc #4; //String
9: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
12: aload_0
13: arraylength
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
17: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
20: astore_1
21: return
So it creates a StringBuilder, appends the "" to it, then appends the int value to it, then calls toString on the StringBuilder instance.
Inside the StringBuilder.append(int) method it ultimately calls Integer.getChars (a package private method).
You can look up the source to the append and getChars in the your copy of the JDK src.zip (or src.jar).
The +
is treated as a string concatenation because a String is on one side of the operand - this would work on 1+""
as well. Thus 1
is implicitly converted into the string "1"
and ""
concatenated with it, resulting in ""+"1"
=> "1"
.
This is sometimes used as a quick and dirty way to convert an integer variable to String, e.g.
String s = "" + myInt;
But the "proper" way to do this would be:
String s = Integer.toString(myInt);
or alternatively:
String s = String.valueOf(myInt);
Edit:
To clarify, the compiler makes this determination and inserts code that will cast the integer into a string before the concatenation is performed.
So basically the compiler sees:
String s = "" + myInt;
And effectively creates bytecode equivalent of
String s = "" + String.valueOf(myInt)
Although it will probably in practice optimize the concatenation away.
Java Language Specification 15.18.1.1 String Conversion
Any type may be converted to type String by string conversion.
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:
- If T is boolean, then use new Boolean(x).
- If T is char, then use new Character(x).
- If T is byte, short, or int, then use new Integer(x).
- If T is long, then use new Long(x).
- If T is float, then use new Float(x).
- If T is double, then use new Double(x).
This reference value is then converted to type String by string conversion.
Now only reference values need to be considered. If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l). Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.
The toString method is defined by the primordial class Object; many classes override it, notably Boolean, Character, Integer, Long, Float, Double, and String.
Some of these quotes are edited for relevance, and emphasis may be added.
JLS 15.18.1 String Concatenation Operator +
If only one operand expression is of type
String
, then string conversion is performed on the other operand to produce a string at run time. The result is a reference to aString
object that is the concatenation of the two operand strings.
JLS 15.18.1.1 String Conversion
- 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:
- If T is
byte
,short
, orint
, then usenew Integer(x)
.- Now only reference values need to be considered. The conversion is performed as if by an invocation of the
toString()
method.
According to this specification, "" + i
is evaluated as if it was written as "" + new Integer(i).toString()
. The operation is string concatenation, which results in a string.
Do note the phrase "as if" in the above passages; only correct behavior is precisely specified, but how that is accomplished under the hood is left to the implementation.
A few things that I omitted from this discussion for now are:
null
is always converted to"null"
- Inlining of compile-time constants (JLS 15.28)
- Optimization using the mutable
StringBuffer
/StringBuilder
(JLS 15.18.1.2)
"a" + "b" is just syntactic sugar for StringBuilder.append("a).append("b"), and since you can .append(1) and it automatically converts it to a String that is what you are seeing.
精彩评论