可能重复:
在 Java 中连接空字符串
请在下面的代码片段中找到
String str = null;
str = str + "hi";
System.out.println(str)
上述代码的输出是nullhi
.
我以为输出会是hi
,对输出感到有点惊讶,却找不到背后的原因。
有人可以解释一下吗。
可能重复:
在 Java 中连接空字符串
请在下面的代码片段中找到
String str = null;
str = str + "hi";
System.out.println(str)
上述代码的输出是nullhi
.
我以为输出会是hi
,对输出感到有点惊讶,却找不到背后的原因。
有人可以解释一下吗。
这是因为append
方法。+
被转换为任一StringBuilder
或StringBuffer
附加操作。
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 对象的数量。
来自 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)。
null
是如果您尝试在 java 中打印空引用时打印的值。
当您将不是所有字符串的值连接在一起时,那些不是字符串的值会像 by 一样转换String.valueOf
。 String.valueOf(null)
是字符串"null"
。
这是 Java 的创建者很早就做出的决定。任何连接到字符串的空值都将输出为null
. 如果您想象您正在尝试输出日志消息,那么这种做法是有道理的:
String personName = null;
System.out.println("Person name is: " + personName);
结果:
人名是:空
这种行为可以在调试时为您提供帮助,因为您知道该变量实际上是 null(而不是空字符串,例如)。
当您尝试这样做时,他们本可以选择简单地抛出异常,但是即使在执行诸如构建日志消息或异常字符串之类的操作时,也会导致很多事情中断。
他们也可以按照您的预期完成,并使空值作为空字符串输出。这就是 .NET 框架所做的。但最终,这不是他们决定做的。
在您显示的示例中,您将字符串 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
所以你得到的输出是正确的。