Java中String的奇怪输出

时间:2012-10-30 18:07:57

标签: java string

  

可能重复:
  Concatenating null strings in Java

请在下面找到代码段

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

System.out.println(str)

上述代码的输出为nullhi

我认为输出会是hi,所以对输出感到惊讶并且无法找到背后的原因。

有人可以解释一下。

6 个答案:

答案 0 :(得分: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对象的数量。

答案 1 :(得分:3)

来自JLS。

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

<强>§15.18.1。 String Concatenation Operator + (reference

  

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

<强>§5.1.11。字符串转换(reference

  

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

答案 2 :(得分:1)

如果您尝试在java中打印空引用,则

null是打印的值。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

这是Java创建者早期做出的决定。连接到字符串的任何空值将输出为null。如果您想象您正在尝试输出日志消息,那么这种情况就有意义了:

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

结果:

  

人名是:null

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

他们本可以选择在您尝试执行此操作时简单地抛出异常,但即使在构建日志消息或异常字符串等操作时,这也会导致许多事情中断。

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

答案 5 :(得分: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

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