2

可能重复:
在 Java 中连接空字符串

请在下面的代码片段中找到

String str = null;
str = str + "hi";

System.out.println(str)

上述代码的输出是nullhi.

我以为输出会是hi,对输出感到有点惊讶,却找不到背后的原因。

有人可以解释一下吗。

4

6 回答 6

4

这是因为append方法。+被转换为任一StringBuilderStringBuffer附加操作。

public AbstractStringBuilder append(String str) {
if (str == null) str = "null";

public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

下面是为您的程序生成的字节码

 0  aconst_null
 1  astore_1 [str]
 2  new java.lang.StringBuilder [16]
 5  dup
 6  aload_1 [str]
 7  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [18]
10  invokespecial java.lang.StringBuilder(java.lang.String) [24]
13  ldc <String "hi"> [27]
15  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [29]
18  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [33]
21  astore_1 [str]
22  getstatic java.lang.System.out : java.io.PrintStream [37]
25  aload_1 [str]
26  invokevirtual java.io.PrintStream.println(java.lang.String) : void [43]
29  return

所以你的代码实际上会被转换成append(null)然后append("hi")这就是为什么你会得到这样的输出

它也清楚地记录在15.18.1. String Concatenation Operator +

实现可以选择在一个步骤中执行转换和连接,以避免创建然后丢弃中间 String 对象。为了提高重复字符串连接的性能,Java 编译器可以使用 StringBuffer 类或类似技术来减少通过计算表达式创建的中间 String 对象的数量。

于 2012-10-30T18:08:55.460 回答
3

来自 JLS。

http://docs.oracle.com/javase/specs/jls/se7/html/index.html

§15.18.1。字符串连接运算符 + (参考)

如果只有一个操作数表达式是字符串类型,则对另一个操作数执行字符串转换(第 5.1.11 节)以在运行时生成字符串。

§5.1.11。字符串转换参考

如果引用为 null,则将其转换为字符串“null”(四个 ASCII 字符 n、u、l、l)。

于 2012-10-30T18:11:44.037 回答
1

null是如果您尝试在 java 中打印空引用时打印的值。

于 2012-10-30T18:09:12.717 回答
1

当您将不是所有字符串的值连接在一起时,那些不是字符串的值会像 by 一样转换String.valueOfString.valueOf(null)是字符串"null"

于 2012-10-30T18:09:28.077 回答
0

这是 Java 的创建者很早就做出的决定。任何连接到字符串的空值都将输出为null. 如果您想象您正在尝试输出日志消息,那么这种做法是有道理的:

String personName = null;
System.out.println("Person name is: " + personName);

结果:

人名是:空

这种行为可以在调试时为您提供帮助,因为您知道该变量实际上是 null(而不是空字符串,例如)。

当您尝试这样做时,他们本可以选择简单地抛出异常,但是即使在执行诸如构建日志消息或异常字符串之类的操作时,也会导致很多事情中断。

他们也可以按照您的预期完成,并使空值作为空字符串输出。这就是 .NET 框架所做的。但最终,这不是他们决定做的。

于 2012-10-30T18:09:28.000 回答
0

在您显示的示例中,您将字符串 null 与 hi 连接,因此生成的输出为
nullhi

String str = null;
str = str + "hi";

System.out.println(str);


as str=str+"hi "//shows one string is concatenating with the other

所以你得到的输出是正确的。

于 2012-10-30T18:20:40.097 回答