在 Java 中连接空字符串
为什么下面的方法有效?我希望抛出一个 NullPointerException
。
String s = null;
s = s + "hello";
System.out.println(s); // prints "nullhello"
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"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么它必须有效?
JLS 5,第 15.18 节.1.1JLS 8 § 15.18.1“字符串连接运算符 +”,导致 JLS 8,§ 5.1.11“字符串转换”,要求此操作成功而不会失败:它是如何工作的?
我们来看看字节码!编译器获取您的代码:
并将其编译为字节码,就像您编写了这样的代码一样:
(您可以通过使用
javap -c
)StringBuilder
的追加方法全部处理空就好了。在本例中,由于null
是第一个参数,因此会调用String.valueOf()
,因为 StringBuilder 没有采用任何任意引用类型的构造函数。如果您改为执行
s = "hello" + s
,则等效代码将是:在本例中,append 方法采用 null 并then 将其委托给
String.valueOf()
。注意: 字符串连接实际上是编译器决定执行哪些优化的罕见位置之一。因此,“完全等效”的代码可能因编译器而异。 JLS 第 15.18 节允许此优化.1.2:
我用来确定上面“等效代码”的编译器是 Eclipse 的编译器 ecj。
Why must it work?
The
JLS 5, Section 15.18.1.1JLS 8 § 15.18.1 "String Concatenation Operator +", leading to JLS 8, § 5.1.11 "String Conversion", requires this operation to succeed without failure:How does it work?
Let's look at the bytecode! The compiler takes your code:
and compiles it into bytecode as if you had instead written this:
(You can do so yourself by using
javap -c
)The append methods of
StringBuilder
all handle null just fine. In this case becausenull
is the first argument,String.valueOf()
is invoked instead since StringBuilder does not have a constructor that takes any arbitrary reference type.If you were to have done
s = "hello" + s
instead, the equivalent code would be:where in this case the append method takes the null and then delegates it to
String.valueOf()
.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:
The compiler I used to determine the "equivalent code" above was Eclipse's compiler, ecj.
请参阅 5.4 和 15.18:
和
See section 5.4 and 15.18 of the Java Language specification:
and
第二行转换为以下代码:
append 方法可以处理
null
参数。The second line is transformed to the following code:
The append methods can handle
null
arguments.您没有使用“null”,因此您不会收到异常。如果你想要 NullPointer,就做
我认为你想做的是:
You are not using the "null" and therefore you don't get the exception. If you want the NullPointer, just do
And I think what you want to do is:
这是 Java API 的
String.valueOf(Object)
方法。当您进行串联时,valueOf
用于获取String
表示形式。如果对象为null
,则有一种特殊情况,在这种情况下,将使用字符串"null"
。This is behavior specified in the Java API's
String.valueOf(Object)
method. When you do concatenation,valueOf
is used to get theString
representation. There is a special case if the Object isnull
, in which case the string"null"
is used.