我正在从事Java代码优化工作。我不清楚String.valueOf
或+""
符号之间的区别:
int intVar = 1;
String strVar = intVar + "";
String strVar = String.valueOf(intVar);
第2行和第3行有什么区别?
答案 0 :(得分:58)
public void foo(){
int intVar = 5;
String strVar = intVar+"";
}
此方法使用StringBuilder创建结果String
public void foo();
Code:
0: iconst_5
1: istore_1
2: new #2; //class java/lang/StringBuilder
5: dup
6: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
9: iload_1
10: invokevirtual #4; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
13: ldc #5; //String
15: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
18: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
21: astore_2
22: return
public void bar(){
int intVar = 5;
String strVar = String.valueOf(intVar);
}
这种方法只调用String
的静态方法来获取int
public void bar();
Code:
0: iconst_5
1: istore_1
2: iload_1
3: invokestatic #8; //Method java/lang/String.valueOf:(I)Ljava/lang/Stri
ng;
6: astore_2
7: return
反过来调用Integer.toString()
答案 1 :(得分:20)
问问自己代码的目的。它是:
听起来更像是后者......这就是我使用String.valueOf
的原因。每当你能够以与描述想要实现的目标相同的方式阅读代码时,这是一件好事。
请注意,这适用于所有类型,并且在传递空引用时返回“null”而不是抛出NullPointerException
。如果你正在使用一个类(不是这个例子中的int
)而你想要它会抛出异常,如果它是null(例如因为它代表一个bug),请调用{{ 1}}而不是引用。
答案 2 :(得分:7)
使用String.valueOf(int)
或更好,Integer.toString(int)
对于机器来说效率相对较高。但是,除非性能至关重要(在这种情况下我不建议你使用)然后""+ x
可以更有效地利用你的时间。恕我直言,这通常更重要。有时候更重要的是。
换句话说,""+
会浪费一个对象,但无论如何Integer.toString()
会创建一些对象。要么您的时间更重要,要么不想不惜一切代价避免创建对象。您极不可能处于创建多个对象的位置,但是创建一个对象并非如此。
答案 3 :(得分:6)
我更喜欢valueOf()
,因为我觉得它更具可读性和显性。
对性能的任何担忧都是无法衡量的微观优化。在我能够进行测量并发现它们有所作为之前,我不会担心它们。
答案 4 :(得分:4)
第一行相当于
String strVal = String.valueOf(intVar) + "";
这样可以做一些额外的(并且毫无意义的)工作。不确定编译器是否使用空字符串文字优化了连接。如果没有(并且看着@Jigar的答案显然没有),这将反过来成为
String strVal = new StringBuilder().append(String.valueOf(intVar))
.append("").toString();
所以你应该直接使用String.valueOf。
答案 5 :(得分:1)
连接字符串和其他变量实际上使用下面的String.valueOf()
(和StringBuilder
),因此编译器将希望丢弃空字符串并在两种情况下生成相同的字节码。
答案 6 :(得分:1)
从优化的角度来看,我总是更喜欢两者之间的String.valueOf()
。第一个只是一个黑客,试图欺骗将intVar
转换为String
因为+运算符。
答案 7 :(得分:0)
尽管这里的答案通常是正确的,但有一点没有提到。
与"" + intVar
或String.valueOf()
相比, Integer.toString()
具有更好的性能。因此,如果性能至关重要,则最好使用空字符串串联。
请参见AlekseyShipilëv的this talk。或these slides的同一演讲(幻灯片#24)
答案 8 :(得分:0)
好吧,如果您研究JRE源代码,Integer.getChars(...)
是最重要的方法,它实际上完成了从整数到char []的转换,但这是一个包私有的方法。
所以问题是如何以最小的开销调用此方法。
以下是通过跟踪对目标方法的调用对这三种方法的概述,请查看JRE源代码以更好地理解这一点。
"" + intVar
编译为:new StringBuilder()
=> StringBuilder.append(int)
=> Integer.getChars(...)
String.valueOf(intVar)
=> Integer.toString(intVar)
=> Integer.getChars(...)
Integer.toString(intVar)
=> Integer.getChars(...)
第一个方法不必要地创建了一个额外的对象,即StringBuilder。
第二个简单地委托给第三个方法。
所以你现在有了答案。
PS:各种编译时和运行时优化在这里起作用。因此,实际性能基准测试可能会根据我们无法预测的不同JVM实现而有所不同,因此我通常更喜欢通过查看源代码看起来高效的方法。
答案 9 :(得分:-1)
String strVar1 = intVar+"";
String strVar2 = String.valueOf(intVar);
strVar1相当于strVar2,但使用int + emptyString“” 这不是优雅的方式。
使用valueOf更有效。