Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中字符串的奇怪输出_Java_String - Fatal编程技术网

Java中字符串的奇怪输出

Java中字符串的奇怪输出,java,string,Java,String,可能重复: 请在下面找到代码片段 String str = null; str = str + "hi"; System.out.println(str) 上述代码的输出为nullhi 我认为输出将是hi,因此对输出感到有点惊讶,无法找到背后的原因 有人能解释一下吗。这是因为append方法+转换为StringBuilder或StringBuffer追加操作 public AbstractStringBuilder append(String str) { if (str == null)

可能重复:

请在下面找到代码片段

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
0 acost\u空
1阿斯托雷1[str]
2新java.lang.StringBuilder[16]
5次重复
6 aload_1[str]
7 invokestatic java.lang.String.valueOf(java.lang.Object):java.lang.String[18]
10调用特殊的java.lang.StringBuilder(java.lang.String)[24]
13最不发达国家[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返回
因此,您的代码实际上会被转换为
append(null)
,然后
append(“hi”)
,这就是为什么您会得到这样的输出

此外,还清楚地记录在

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


null
是在java中打印空引用时打印的值。

这是java创建者早期做出的决定。连接到字符串的任何空值都将作为
null
输出。如果您设想您正试图输出一条日志消息,那么这种方式是有意义的:

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

人名为:空

这种行为可以在调试时帮助您,因为您知道变量实际上为null(例如,与空字符串相反)

当您尝试这样做时,他们可以选择简单地抛出一个异常,但在构建日志消息或异常字符串等操作时,这会导致很多事情收支平衡


它们也可以按照您的预期执行,并使null值作为空字符串输出。这就是.NET框架所做的。但归根结底,这并不是他们决定要做的。

当您将并非所有字符串的值连接在一起时,那些未被转换的值就像被
String.valueOf
转换一样<代码>字符串。valueOf(null)是JLS中的字符串
“null”

第15.18.1节。字符串连接运算符+()

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

§5.1.11。字符串转换()

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


在您展示的示例中 您正在将字符串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

因此,您得到的输出是正确的。

但是
str
是一个字符串,所以这不能解释它。
null
不是字符串(实际上它不是任何对象)。您的意思是指编译器生成代码,动态检查是否使用
String.valueOf
?您的含义是错误的:
String。对于
+
的所有引用类型参数,总是调用valueOf
。公平地说,我试图描述效果,而不是机制。如果您只说“所有操作数都像通过
String.valueOf
一样进行转换”,效果的描述也会更简单我只用了5秒钟就得到了那篇文章的链接。请定期使用谷歌。我不确定谷歌搜索使用的文本,所以直接发布在这里。这些都是好的和有趣的事实,但OP观察的真正原因不在于编译器实现的细节,但是JLS清楚地指定了连接运算符的语义。@MarkoTopolnik您的评论总是增加了我的知识。从
JLS