在Java中连接空字符串

时间:2010-11-23 20:45:20

标签: java string concatenation string-concatenation

为什么以下工作?我希望抛出NullPointerException

String s = null;
s = s + "hello";
System.out.println(s); // prints "nullhello"

5 个答案:

答案 0 :(得分:174)

为什么必须才有效?

导致JLS 5, Section 15.18.1.1JLS 8 § 15.18.1 "String Concatenation Operator +" JLS 8, § 5.1.11 "String Conversion"要求此操作成功而不会失败:

  

...现在只需要考虑参考值。 如果引用为null,则将其转换为字符串“null”(四个ASCII字符n,u,l,l)。否则,执行转换就好像通过调用没有参数的引用对象的toString方法一样;但是如果调用toString方法的结果为null,则使用字符串“null”。

如何运作?

让我们看一下字节码!编译器接受您的代码:

String s = null;
s = s + "hello";
System.out.println(s); // prints "nullhello"

并将其编译为字节码,就像你写了这样:

String s = null;
s = new StringBuilder(String.valueOf(s)).append("hello").toString();
System.out.println(s); // prints "nullhello"

(您可以使用javap -c

自行完成

StringBuilder的追加方法都处理null就好了。在这种情况下,因为null是第一个参数,所以调用String.valueOf(),因为StringBuilder没有采用任意引用类型的构造函数。

如果您要完成s = "hello" + s,则等效代码为:

s = new StringBuilder("hello").append(s).toString();

在这种情况下,append方法取空,然后然后将其委托给String.valueOf()

注意:字符串连接实际上是编译器决定执行哪些优化的罕见地方之一。因此,“完全等效”代码可能因编译器而异。 JLS, Section 15.18.1.2允许此优化:

  

为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似技术来减少通过表达式求值创建的中间String对象的数量。

我用来确定上面“等效代码”的编译器是Eclipse的编译器, ecj

答案 1 :(得分:23)

请参阅Java语言规范的5.415.18部分:

  

字符串转换仅适用于   二进制+运算符的操作数   其中一个参数是String。在   这个单一的特例,另一个   +的参数转换为a   字符串,以及一个新的String   这两个字符串的连接是   +的结果。字符串转换   在...中详细说明   字符串的描述   连接+运算符。

  

如果只有一个操作数表达式   键入String,然后进行字符串转换   在另一个操作数上执行   在运行时生成一个字符串。该   result是对String的引用   对象(新创建的,除非   expression是一个编译时常量   表达式(§15.28))即   两个操作数的串联   字符串。的人物   左手操作数先于   右手操作数的字符   在新创建的字符串中。如果   那么String类型的操作数是null   使用字符串“null”代替   那个操作数。

答案 2 :(得分:11)

第二行转换为以下代码:

s = (new StringBuilder()).append((String)null).append("hello").toString();

append方法可以处理null个参数。

答案 3 :(得分:10)

您没有使用“null”,因此您没有获得异常。如果您想要NullPointer,只需执行

String s = null;
s = s.toString() + "hello";

我认为你想要做的是:

String s = "";
s = s + "hello";

答案 4 :(得分:7)

这是Java API的String.valueOf(Object)方法中指定的行为。进行连接时,valueOf用于获取String表示。如果对象是null,则会有一种特殊情况,在这种情况下使用字符串"null"

  

public static String valueOf(Object obj)

     

返回Object参数的字符串表示形式。

     

参数:       obj - 一个对象。

     

返回:

     

如果参数为null,则字符串等于“null”;否则,返回obj.toString()的值。