一开始听起来可能很奇怪,看似简单,但我坚持了预期的观点。我认为在以下代码中,text
和s
引用了t
,作为输出,我会得到hello world hello world
,但没有。我得到hello world
。
class Test2 {
private volatile static String text = "";
public static void main(String[] args) {
String s = text;
text = "hello world";
String t = text;
System.out.println(s + " " + t);
}
}
到目前为止,我错过了哪一点?我真的对此感到困惑。大概在那里隐式创建一个新对象。但是为什么呢?
以下是与Java无关的知识,而是与C知识有关的知识。我尝试用C解释上述代码。在那里,我得到了预期的结果,hello world hello world
。
#include <stdio.h>
int main()
{
char const volatile * volatile x = "";
char const volatile * volatile const * xPtr = &x;
x = "hello world";
char const volatile * volatile const * xPtr2 = &x;
printf("%s %s\n", *xPtr, *xPtr2);
return 0;
}
答案 0 :(得分:4)
我得到了世界问候。
您应该在开头添加两个空格。
到目前为止,我错过了哪一点?
使用调试器向您显示原因,但是总之,您只有Java中的引用和原语。没有引用。
char const volatile * volatile const * xPtr = &x;
Java中没有类似的东西。
大概是在那里隐式创建一个新对象。
隐式创建了一个新的StringBuilder
和一个新的char[]
,但是我认为这不是您的意思。
逐步执行代码
String s = text; // text = "", s = ""
text = "hello world"; // text = "hello world", s = ""
String t = text; // text & t = "hello world", s = ""
System.out.println(s + " " + t);
答案 1 :(得分:2)
您的问题在这里s = text
。您认为通过执行s
是指向text
(他自己指向""
)的引用。但是它的作用是评估文本的值并使s
指向文本,因此s
指向""
而不是text
。
然后,当您执行text = "hello";
时,无需将对象""
更改为"hello"
,只需使text
指向一个新对象(它会停止指向{{1} },现在指向""
)
因此,当您打印全部内容时,它将评估"hello"
(= s
)和t(= ""
)
答案 2 :(得分:2)
您的两个代码段不相同。
在C示例中有指针,但在Java示例中没有。实际上,C语言中的等效代码为:
#include <stdio.h>
int main()
{
char const *text = ""; // text points to a memory location that contains the string ""
char const *s = text; // s now points to the same memory location
text = "hello world"; // text now points to another memory location that contains the string "hello world", s continues pointing to the memory location where the string "" is
char const *t = text; // t now points to the memory location that text points to, which is the one containing "hello world"
printf("%s %s\n", s, t);
return 0;
}
与Java示例中得到的结果相同。
由于Java没有指针语义,因此除非使用某种Holder
类包装String对象,否则您将无法实现在Java中试图实现的目标。