首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在我的字符串连接字节码中会调用"String.valueOf(Object)“?

为什么在我的字符串连接字节码中会调用"String.valueOf(Object)“?
EN

Stack Overflow用户
提问于 2013-05-04 01:01:36
回答 1查看 1.9K关注 0票数 5

我在一个小的微基准测试应用程序(运行JDK 1.6)中有以下两种方法:

代码语言:javascript
复制
public static String testStringBuilder3(String str1, String str2, String str3, String str4, String str5) {
    return new StringBuilder(str1).append("-").append(str2).append("-").append(str3).append("-").append(str4).append("-").append(str5).toString();
}

public static String testStringBuilder4(String str1, String str2, String str3, String str4, String str5) {
    return str1 + "-" + str2 + "-" + str3 + "-" + str4 + "-" + str5;
}

我希望这两个方法的字节码是相同的。它们几乎是相同的,只有一个我想要理解的小差异。

下面是第一个方法的字节码(我无法让StackOverflow正确地格式化它):

代码语言:javascript
复制
public static java.lang.String testStringBuilder3(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
Code:
  0:    new #164; //class java/lang/StringBuilder
  3:    dup
  4:    aload_0
  5:    invokespecial   #170; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  8:    ldc #182; //String -
 10:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 13:    aload_1
 14:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 17:    ldc #182; //String -
 19:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 22:    aload_2
 23:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 26:    ldc #182; //String -
 28:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 31:    aload_3
 32:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 35:    ldc #182; //String -
 37:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 40:    aload   4
 42:    invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 45:    invokevirtual   #176; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
 48:    areturn

下面是第二个方法的字节码:

代码语言:javascript
复制
public static java.lang.String testStringBuilder4(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
Code:
  0:    new #164; //class java/lang/StringBuilder
  3:    dup
  4:    aload_0
  5:    invokestatic    #166; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
  8:    invokespecial   #170; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  11:   ldc #182; //String -
  13:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  16:   aload_1
  17:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  20:   ldc #182; //String -
  22:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  25:   aload_2
  26:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  29:   ldc #182; //String -
  31:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  34:   aload_3
  35:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  38:   ldc #182; //String -
  40:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  43:   aload   4
  45:   invokevirtual   #172; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  48:   invokevirtual   #176; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  51:   areturn

这两种方法之间的唯一区别是第二种方法的以下字节码行:

代码语言:javascript
复制
   5:   invokestatic    #166; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;

这可能是在做什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-04 01:07:32

在JDK源代码中:

代码语言:javascript
复制
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

它确保第一个变量不为空,否则它将抛出NullPointerException,因为这是StringBuilder(String str)的预期行为

示例:

代码语言:javascript
复制
public class StringTest
{
  public static void main(String a[])
  {
    System.out.println(testStringBuilder3(null, null, null, null, null));
    System.out.println(testStringBuilder4(null, null, null, null, null));
  }
 public static String testStringBuilder3(String str1, String str2, String str3, String str4, String str5) {
    return str1 + "-" + str2 + "-" + str3 + "-" + str4 + "-" + str5;
  }
  public static String testStringBuilder4(String str1, String str2, String str3, String str4, String str5) {
    return new StringBuilder(str1).append("-").append(str2).append("-").append(str3).append("-").append(str4).append("-").append(str5).toString();
  }
}

输出:

代码语言:javascript
复制
null-null-null-null-null
Exception in thread "main" java.lang.NullPointerException
    at java.lang.StringBuilder.<init>(Unknown Source)
    at StringTest.testStringBuilder3(StringTest.java:15)
    at StringTest.main(StringTest.java:11)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16364151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档