从字节码和源码角度来理解String.valueOf()、toString()、i+““的效率关系

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`String.valueOf()`和`toString()`都是用于将对象转换为字符串的方法,但它们之间有一些区别。 1. `String.valueOf()`方法:`String.valueOf()`是一个静态方法,它接受一个参数并返回与参数对应的字符串表示。这个方法可以处理各种类型的参数,包括基本数据类型和对象。如果参数是一个对象,它会调用对象的`toString()`方法来获取字符串表示。如果参数是`null`,它会返回字符串"null"。 以下是使用`String.valueOf()`的示例: ```java int num = 10; String str1 = String.valueOf(num); // "10" Double d = 3.14; String str2 = String.valueOf(d); // "3.14" Object obj = new Object(); String str3 = String.valueOf(obj); // 调用obj的toString()方法来获取字符串表示 String str4 = String.valueOf(null); // "null" ``` 2. `toString()`方法:`toString()`是一个定义在`Object`类中的方法,所有的Java对象都继承了这个方法。默认情况下,`toString()`返回一个包含对象类名和哈希码的字符串表示。但是,你可以根据需要在自定义类中重写这个方法,以便返回更有意义的字符串表示。 以下是重写`toString()`方法的示例: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class Main { public static void main(String[] args) { Person person = new Person("John", 25); String str = person.toString(); // "Person{name='John', age=25}" } } ``` 在上面的示例中,`Person`类重写了`toString()`方法,以返回一个包含姓名和年龄的字符串表示。 总结来说,`String.valueOf()`是一个静态方法,用于将任何类型的参数转换为字符串表示,而`toString()`是一个在`Object`类中定义的方法,用于将对象转换为字符串。如果你需要获取一个对象的字符串表示,通常最好使用`toString()`方法,在自定义类中重写这个方法以提供更有意义的字符串表示。如果你只是想将其他类型转换为字符串,可以使用`String.valueOf()`方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值