在Java中连接空字符串 [英] Concatenating null strings in Java

查看:218
本文介绍了在Java中连接空字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why does the following work? I would expect a NullPointerException to be thrown.

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


推荐答案

为什么必须它有用吗?



JLS 5,第15.18.1.1节 JLS8§15.18.1String Concatenation Operator +,导致 JLS 8,§5.1.11字符串转换,要求此操作成功而不失败:

Why must it work?

The JLS 5, Section 15.18.1.1 JLS 8 § 15.18.1 "String Concatenation Operator +", leading to JLS 8, § 5.1.11 "String Conversion", requires this operation to succeed without failure:


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

...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.



如何运作?



我们来看看字节码吧!编译器接受你的代码:

How does it work?

Let's look at the bytecode! The compiler takes your code:

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

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

and compiles it into bytecode as if you had instead written this:

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没有采用任意引用类型的构造函数。

The append methods of StringBuilder all handle null just fine. In this case because null is the first argument, String.valueOf() is invoked instead since StringBuilder does not have a constructor that takes any arbitrary reference type.

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

If you were to have done s = "hello" + s instead, the equivalent code would be:

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

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

where in this case the append method takes the null and then delegates it to String.valueOf().

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

Note: String concatenation is actually one of the rare places where the compiler gets to decide which optimization(s) to perform. As such, the "exact equivalent" code may differ from compiler to compiler. This optimization is allowed by JLS, Section 15.18.1.2:


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

To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

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

The compiler I used to determine the "equivalent code" above was Eclipse's compiler, ecj.

这篇关于在Java中连接空字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆