Java字符串拼接效率的比较和对String.valueOf的思考

本文探讨了在Java中使用String.valueOf与""+value进行字符串拼接的效率差异,通过字节码分析和性能测试,揭示了String.valueOf在某些场景下可能不如""+value高效。文章举例了Android日志打印中的实践,并提供了优化建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天看到的关于Java的一篇文章(《阿里资深工程师教你如何优化Java代码》)中有写到使用String.valueOf(value)代替 “” + value的建议,原因是“当要把其他对象或类型转换为字符串时,使用String.valueOf(value)比""+value的效率更高。”
反例:

int i = 1;
String s = "" + i;

正例:

int i = 1;
String s = String.valueOf(i);

当看到上面的建议的时候是认同的,后来仔细一想Android framework上面log的写法都是下面的方式:

int num = 1;
int count = 2;
Rlog.d(LOG_TAG, "the num:" + num + ", the count:" + count);

而Rlog.d的原型函数如下:

\frameworks\base\telephony\java\android\telephony\Rlog.java
public static int (String tag, String msg) {
    // native实现
}

函数实现上看,打印的日志信息就是String类型的,Android中的使用方法就是反例,效率不高。是不是应该改成

int num = 1;
int count = 2;
Rlog.d(LOG_TAG, "the num:" + String.valueOf(num) + ", the count:" + String.valueOf(count));

但是Android code中几乎看不到上面这种写法,那就奇怪了,Android中打印的log数量还是很可观的,尤其是测试版本上,log更是很多。那Android为什么不使用String.valueOf呢?难道Android错了?当问题提出后,我打算通过字节码看一下反例和正例的差别,另外就是通过实际测试看一下两种效率的差异。

有些问题通过字节码就能看出端倪。下面是需要转译字节码的原始code,比较常用,尤其是打印log,字符串和整数拼接出一个新的自付出。

public class TestValueOf {
public static void main(String[] args) {
    int i = 0;
    String s = "abcdef";
    String s1 = s + i;
    System.out.println(s1);
    String d = "abcdef";
    String d1 = d + String.valueOf(i);
    System.out.println(d1);
}
}

下面是对应生成的字节码:

public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=6, args_size=1
0: iconst_0
1: istore_1
2: ldc #2 // String abcdef
4: astore_2
5: new #3 // class java/lang/StringBuilder
8: dup
9: invokespecial #4 // Method java/lang/StringBuilder.""?)V
12: aload_2
13: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: iload_1
17: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
20: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: astore_3
24: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
27: aload_3
28: invokevirtual #9 // Method java/io/PrintStr

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值