当我做“”+1我得到一个字符串 - 为什么

时间:2010-03-19 16:52:44

标签: java

首先请理解我完全理解Java在使用“”+ int时会返回一个字符串。

我真正不确定的是在内存方面究竟发生了什么。 java执行此转换的确切方式。我的意思是非常深刻,不是'自动拳击'或类似的东西:)

我希望有更深入了解的人可以解释究竟做了什么。

5 个答案:

答案 0 :(得分:9)

实际上,对于“”+ 1,编译器会创建一个值为“1”的String常量字符串,并将其放入常量池中 - 因此在运行时不会执行任何操作。

如果你有“”+ x(其中x是一个int变量),你会得到以下字节码(来自当前的JDK 1.6):

  0:   new     #2; //class java/lang/StringBuilder
  3:   dup
  4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
  7:   ldc     #4; //String
  9:   invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  12:  aload_0
  13:  arraylength
  14:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  17:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  20:  astore_1
  21:  return

因此它创建一个StringBuilder,将“”附加到它,然后将int值附加到它,然后在StringBuilder实例上调用toString。

在StringBuilder.append(int)方法中,它最终调用Integer.getChars(包私有方法)。

您可以在JDK src.zip(或src.jar)的副本中查找append和getChars的源代码。

答案 1 :(得分:8)

+被视为字符串连接,因为字符串位于操作数的一侧 - 这也适用于1+""。因此,1被隐式转换为与其串联的字符串"1""",从而导致""+"1" =&gt; "1"

这有时被用作将整数变量转换为String的快速而肮脏的方式,例如

String s = "" + myInt;

但这样做的“正确”方法是:

String s = Integer.toString(myInt);

或者:

String s = String.valueOf(myInt);

编辑:

为了澄清,编译器进行此确定并插入将在执行串联之前将整数转换为字符串的代码。

基本上编译器看到了:

String s = "" + myInt;

并有效地创建等效于

的字节码
String s = "" + String.valueOf(myInt)

虽然它可能在实践中优化了连接。

答案 2 :(得分:6)

Java语言规范15.18.1.1 String Conversion

  

任何类型都可以转换为String类型   字符串转换

     

值x   原始类型T首先转换为   一个参考值,好像通过给它   作为适当阶级的论据   实例创建表达式:

     
      
  • 如果T是布尔值,则使用new   布尔(X)。
  •   
  • 如果T为char,则使用   新字符(x)。
  •   
  • 如果T是字节,   short,或int,然后使用new   整数(X)。
  •   
  • 如果T很长,则使用   新龙(x)。
  •   
  • 如果T是浮点数,则使用   new Float(x)。
  •   
  • 如果T是两倍,那么   使用新的Double(x)。
  •   
     

此参考   然后将值转换为String类型   通过字符串转换。

     

现在只有   参考值需要   考虑。如果引用为null,   它被转换为字符串“null”   (四个ASCII字符n,u,l,l)。   否则,执行转换   好像是通过调用toString   引用对象的方法   没有争论;但如果结果   调用toString方法为null,   然后使用字符串“null”   代替。

     

toString方法由。定义   原始类对象;很多课程   覆盖它,特别是布尔值,   字符,整数,长,浮点数,   Double和String。

答案 3 :(得分:2)

其中一些引号会根据相关性进行编辑,并且可能会重点强调。

JLS 15.18.1 String Concatenation Operator +

  

如果只有一个操作数表达式是String类型,则在另一个操作数上执行字符串转换以在运行时生成字符串。结果是对String对象的引用,该对象是两个操作数字符串的串联。

JLS 15.18.1.1 String Conversion

  
      
  • 原始类型T的值x首先通过将其作为适当的类实例创建表达式的参数转换为参考值,就像一样:      
        
    • 如果T为byteshortint,则使用new Integer(x)
    •   
  •   
  • 现在只需要考虑参考值。通过调用toString()方法,就像一样执行转换。
  •   

根据此规范,"" + i被评估为,好像被写为"" + new Integer(i).toString()。该操作是字符串连接,这会产生一个字符串。

请注意上述段落中的“,如同”一样;只有精确指定了正确的行为,但是如何在幕后完成这项工作留待实施。

我现在讨论的一些事情是:

  • null始终转换为"null"
  • 内联编译时常量(JLS 15.28
  • 使用可变StringBuffer / StringBuilderJLS 15.18.1.2)进行优化

答案 4 :(得分:0)

“a”+“b”只是StringBuilder.append(“a).append(”b“)的语法糖,因为你可以.append(1)并自动将它转换为一个字符串就是什么你看到了。