结论:String.valueOf() = toString() > i+""
测试代码
public class Test {
public static void main(String[] args) {
int i = 1;
String a = "";
a = String.valueOf(i);
a = Integer.toString(i);
a = i + "";
}
}
代码分析
我们来看一下String类中的valueOf()方法源码,如下:
public static String valueOf(int i) {
return Integer.toString(i);
}
可以看出String.valueOf(i)
内部就是Integer.toString(i)
,所以String.valueOf() 和 toString()效率相等
,可不要想着valueOf方法
点进去才是Integer.toString(i)
,我相信这不会浪费多少时间
现在的重点就变成了比较Integer.toString(i)
和i+""
的快慢了,现在我们来看看一下main方法的字节码文件,如下:
0 iconst_1
1 istore_1
2 ldc #2
4 astore_2
5 iload_1
6 invokestatic #3 <java/lang/String.valueOf>
9 astore_2
10 iload_1
11 invokestatic #4 <java/lang/Integer.toString>
14 astore_2
15 new #5 <java/lang/StringBuilder>
18 dup
19 invokespecial #6 <java/lang/StringBuilder.<init>>
22 iload_1
23 invokevirtual #7 <java/lang/StringBuilder.append>
26 ldc #2
28 invokevirtual #8 <java/lang/StringBuilder.append>
31 invokevirtual #9 <java/lang/StringBuilder.toString>
34 astore_2
35 return
下标为11
的那一行是Integer.toString(i)方法的灵魂,其他就没什么代码了
我们再来看下标15到31
行,可以看到里面在创建StringBuilder对象,然后复制该对象,并且执行了两次该对象的append()方法(第一次添加i,第二次添加""),最后执行了一次toString()方法。
StringBuilder对象的创建和复制代码我们就不看了,我们来看StringBuilder对象
的append(i)源码
,这是整个添加的灵魂所在,如下:
// StringBuilder.class
@Override
public StringBuilder append(int i) {
super.append(i);
return this;
}
// AbstractStringBuilder.class
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
append("-2147483648");
return this;
}
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
}
然后我们来看Integer.append(i)方法源码
:
// Integer.class
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
我们来用一张图来对比一下上面两个源码,如下:
大家也看出来了StringBuilder对象
的append(i)源码
和Integer.append(i)方法源码
几乎一致,只不过前者比后者少了一个new String()
对象创建操作,我们在前面的字节码文件中看到下标31的那行会调用StringBuilder对象的toString方法,我们来看一下该方法,如下:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
你看到了这里面也是一个String对象的创建操作,所以StringBuilder对象
调用的append(i)
加上Integer.toString(i)
就等于Integer.append(i)
,用字节码文件来表示如下:
然而i+""
还涉及到StringBuilder对象的创建、复制、调用一次append()方法,所以综上所述Integer.toString(i)的效率大于i+""
因此:String.valueOf() = toString() > i+""