2014-09-03 131 views
3

我是java的初学者。我对String上的+=操作有疑问。为什么我可以使用+=运算符在没有双引号的情况下附加String对象?字符串追加没有双引号

比如我就在这一段代码

String s1 = "abc"; 
String s1+=42; 

当我其实是想,我必须使用s1+="42"没有编译器错误;

+0

你有一个名为'def'范围变量? – 2014-09-03 05:36:36

+0

有很好的解释了这个问题 http://stackoverflow.com/questions/47605/string-concatenation-concat-vs-operator – 2014-09-03 05:44:48

回答

2
String s1+=def; 

该行有效,然后def是另一个Java String。由于它成功之前,你的代码编译,一些地方,你有

String def ="someDeclaredStringBefore"; 

**Update:** 

要得到什么happennig那里,首先让我们看看如何+作品上字符串的清晰度。

它使用StringBuilder附加方法。对于前

StringBuilder compilerGeneratedBuilder = new StringBuilder(); 
compilerGeneratedBuilder.append("str"); 
compilerGeneratedBuilder.append("ingcon"); 
compilerGeneratedBuilder.append("catenation"); 
String finalString = compilerGeneratedBuilder.toString(); 

全文我最近写在这里:

http://codeinventions.blogspot.com/2014/08/compiler-version-string-concatenation.html

当你写String r += 42;

既然你想添加一个int值。对应的append(int i)方法调用StringBuilder和最终的字符串生成。

+0

这并不一定非得是'String'。哦,他们刚刚更新了他们的问题。 – 2014-09-03 05:47:37

+0

@SotiriosDelimanolis感谢您的注意。我刚刚写下并退出了此页面。不知道编辑。我也编辑了这篇文章。 – 2014-09-03 05:56:31

2

使用这段代码模拟你的问题上面:

String s = "asd"; 
    s+=42; 
    System.out.println(s); 

会导致这种byteCote:

Code: 
     0: ldc   #16     // String asd 
     2: astore_1 
     3: new   #18     // class java/lang/StringBuilder 
     6: dup 
     7: aload_1 
     8: invokestatic #20     // Method java/lang/String.valueOf:(
java/lang/Object;)Ljava/lang/String; 
    11: invokespecial #26     // Method java/lang/StringBuilder."< 
nit>":(Ljava/lang/String;)V 
    14: bipush  42 
    16: invokevirtual #29     // Method java/lang/StringBuilder.ap 
end:(I)Ljava/lang/StringBuilder; 
    19: invokevirtual #33     // Method java/lang/StringBuilder.to 
tring:()Ljava/lang/String; 
    22: astore_1 
    23: getstatic  #37     // Field java/lang/System.out:Ljava/ 
o/PrintStream; 
    26: aload_1 
    27: invokevirtual #43     // Method java/io/PrintStream.printl 
:(Ljava/lang/String;)V 
    30: return 

16号和19你可以清楚地看到,它调用的StringBuilder并在append method内部拨打+= operator(附加42),然后在line 19中将其转换为字符串。

编辑:

上面的代码实际上是在说这样的:s = s + 42,所以每次使用加法运算的整数的字符串,它会调用它的包装类,并调用toString方法

JLS

Any type may be converted to type String by string conversion. 

A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression (§15.9): 

If T is boolean, then use new Boolean(x). 

If T is char, then use new Character(x). 

If T is byte, short, or int, then use new Integer(x). 

If T is long, then use new Long(x). 

If T is float, then use new Float(x). 

If T is double, then use new Double(x). 

This reference value is then converted to type String by string conversion. 
Now only reference values need to be considered: 

If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l). 

Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead. 
+0

找到JLS的相关部分并引用它不是更好吗?看着编译器的输出是粗糙的......如果这是一个编译器错误呢? – 2014-09-03 05:52:59

+0

@nem如果你正在使用windows转到命令提示符和'cd to_folder_of_your_project/bin'并在使用'javap -c NAME_OF_CLASS'后 – 2014-09-03 05:53:16

+0

@StephenC增加/ – 2014-09-03 06:02:10

1
String s1 = "abc"; 
String s1+=42; 

这工作,因为42是一个int

加号+重载运算符在Java中。它可以添加数字或追加字符串。

  1. 如果你在两个数字上都使用+,它会添加它。

    System.out.println(1+1); //2

  2. 如果你使用它在两个字符串,将追加字符串。

    System.out.println("abc"+"def"); //abcdef

  3. 如果您在数字和字符串的组合使用它,它只会追加一起。

    System.out.println(1+"1"); //11

更多信息check out this article on Oracle