结论: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+""


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

从源代码角度来分析HashSet、TreeSet的区别