String valueOf vs与空字符串连接

时间:2011-10-13 09:54:17

标签: java

我正在从事Java代码优化工作。我不清楚String.valueOf+""符号之间的区别:

int intVar = 1;
String strVar = intVar + "";
String strVar = String.valueOf(intVar);

第2行和第3行有什么区别?

10 个答案:

答案 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

的String版本
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)

尽管这里的答案通常是正确的,但有一点没有提到。

"" + intVarString.valueOf()相比,

Integer.toString()具有更好的性能。因此,如果性能至关重要,则最好使用空字符串串联。

请参见AlekseyShipilëv的this talk。或these slides的同一演讲(幻灯片#24)

答案 8 :(得分:0)

好吧,如果您研究JRE源代码,Integer.getChars(...)是最重要的方法,它实际上完成了从整数到char []的转换,但这是一个包私有的方法。
所以问题是如何以最小的开销调用此方法。
以下是通过跟踪对目标方法的调用对这三种方法的概述,请查看JRE源代码以更好地理解这一点。

  1. "" + intVar编译为:
    new StringBuilder() => StringBuilder.append(int) => Integer.getChars(...)
  2. String.valueOf(intVar) => Integer.toString(intVar) => Integer.getChars(...)
  3. Integer.toString(intVar) => Integer.getChars(...)

第一个方法不必要地创建了一个额外的对象,即StringBuilder。
第二个简单地委托给第三个方法。
所以你现在有了答案。

PS:各种编译时和运行时优化在这里起作用。因此,实际性能基准测试可能会根据我们无法预测的不同JVM实现而有所不同,因此我通常更喜欢通过查看源代码看起来高效的方法。

答案 9 :(得分:-1)

String strVar1 = intVar+"";
String strVar2 = String.valueOf(intVar);

strVar1相当于strVar2,但使用int + emptyString“” 这不是优雅的方式。

使用valueOf更有效。