【问题标题】:Difference between String.valueOf(long a) and concatenating ("" + a)String.valueOf(long a) 和连接 ("" + a) 之间的区别
【发布时间】:2013-02-25 03:14:24
【问题描述】:

哪种方法更好,为什么?

如果我写

cmissValue = String.valueOf(callDBDatasource.cMiss());

cmissValue = "" + callDBDatasource.cMiss();

应该采用什么方法?

【问题讨论】:

  • 我猜标题很长
  • 我认为第二个创建了更多String。但你可以很容易地自己证明。
  • 好吧,就我所见,它们都是空安全的,因为 cmissValue 不会为空。这在问题的背景下是否有意义或有意,我不能说:)

标签: java


【解决方案1】:
"" + callDBDatasource.cMiss();

将编译为:

new StringBuilder().append("").append(callDBDatasource.cMiss()).toString();

这将创建一个新对象,因此会明显变慢。看到这个问题:Is string concatenaion really that slow?

【讨论】:

  • 编译器没有检测到foo = "" + bar;这样的情况并将它们转换为foo = bar.toString()
  • 如果bar 是原始数据类型(如int),则它没有toString() 方法。
  • 那转换成foo = String.valueOf(bar)怎么样?
  • @AmitG:看看我下面的答案,看看这两个方法生成的字节码。
  • @cdmckay 很好的答案!那么字符串池在哪里?为什么java现在需要StringBuilder帮助?现在我将研究它..
【解决方案2】:

这在这里很有用(“将数字转换为字符串”部分):http://www.odi.ch/prog/design/newbies.php

很快:

    String.valueOf(callDBDatasource.cMiss());

【讨论】:

  • 请给初学者一个更简单的总结
  • 转到链接并搜索“将数字转换为字符串”,它只有几行。我把它留在这里是因为它可能对其他问题有用,当我开始写它时没有答案。
【解决方案3】:

对于那些感兴趣的人,我已经对这两种情况进行了建模并为它们生成了字节码。

这是第一种情况的程序:

import java.util.Random;

public class Test1 {
  public static void main(String[] args) {
    long l = new Random().nextLong();
    String s = String.valueOf(l);
    System.out.println(s);
  }
}

...这是字节码:

0:  new             #2; //class java/util/Random
3:  dup
4:  invokespecial   #3; //Method java/util/Random."<init>":()V
7:  invokevirtual   #4; //Method java/util/Random.nextLong:()J
10: lstore_1
11: lload_1
12: invokestatic    #5; //Method java/lang/String.valueOf:(J)Ljava/lang/String;
15: astore_3
16: getstatic       #6; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_3
20: invokevirtual   #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: return

这是你所期望的。

现在,这是对第二种情况进行建模的程序:

import java.util.Random;

public class Test2 {
  public static void main(String[] args) {
    long l = new Random().nextLong();
    String s = "" + l;
    System.out.println(s);
  }
}

...这是字节码:

0:  new             #2;  //class java/util/Random
3:  dup
4:  invokespecial   #3;  //Method java/util/Random."<init>":()V
7:  invokevirtual   #4;  //Method java/util/Random.nextLong:()J
10: lstore_1
11: new             #5;  //class java/lang/StringBuilder
14: dup
15: invokespecial   #6;  //Method java/lang/StringBuilder."<init>":()V
18: ldc             #7;  //String 
20: invokevirtual   #8;  //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: lload_1
24: invokevirtual   #9;  //Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
27: invokevirtual   #10; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
30: astore_3
31: getstatic       #11; //Field java/lang/System.out:Ljava/io/PrintStream;
34: aload_3
35: invokevirtual   #12; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
38: return

如您所见,生成的字节码比第一种情况多得多。您还可以看到(在 11 到 27 处)StringBuilder 用于连接值,如接受的答案中所述。

【讨论】:

  • 该死的,我只差几秒钟就可以自己发帖了。好吧,无论如何证明我的权利:D
猜你喜欢
  • 1970-01-01
  • 2016-02-17
  • 2017-12-24
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2016-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多