Java String=运算符引用或在此情况下创建新字符串对象

Java String=运算符引用或在此情况下创建新字符串对象,java,string,object,Java,String,Object,一开始可能听起来很奇怪,可能看起来很简单,但我还是坚持住了这一点。我想在下面的代码中,text被s和t引用,作为输出,我会得到hello world,但不是。我得到了你好世界 class Test2 { private volatile static String text = ""; public static void main(String[] args) { String s = text; text = "hello world";

一开始可能听起来很奇怪,可能看起来很简单,但我还是坚持住了这一点。我想在下面的代码中,
text
s
t
引用,作为输出,我会得到
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);
    }
}
#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;
}
到现在为止我错过了什么?我真的很困惑。假定在那里隐式创建了一个新对象。但是为什么呢


下面的一个不是相关的Java,而是C-knowers。我尝试用C语言解释上面的代码。我在那里得到了预期的结果,
helloworld helloworld

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);
    }
}
#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;
}
#包括
int main()
{
char const volatile*volatile x=“”;
char const volatile*volatile const*xPtr=&x;
x=“你好,世界”;
char const volatile*volatile const*xPtr2=&x;
printf(“%s%s\n”、*xPtr、*xPtr2);
返回0;
}
我得到了你好世界

你应该在开始的时候有两个空格

到现在为止我错过了什么

使用调试器可以说明原因,但简而言之,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);
我得到了你好世界

你应该在开始的时候有两个空格

到现在为止我错过了什么

使用调试器可以说明原因,但简而言之,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);

您的问题在这里
s=text
。您认为,通过这样做,
s
是一个指向
text
(他自己指向
)的引用。但它所做的是评估文本的值,并使
s
指向它,因此
s
指向
,而不是
文本

然后当您执行
text=“hello”
您不会将对象
更改为
“hello”
您只需将
文本
指向一个新对象(它停止指向
,现在指向
“hello”


因此,当您打印整个内容时,它会计算
s
(=
)和t(
“hello”

,您的问题就在这里
s=text
。您认为,通过这样做,
s
是一个指向
text
(他自己指向
)的引用。但它所做的是评估文本的值,并使
s
指向它,因此
s
指向
,而不是
文本

然后当您执行
text=“hello”
您不会将对象
更改为
“hello”
您只需将
文本
指向一个新对象(它停止指向
,现在指向
“hello”


因此,当您打印整个内容时,它会计算
s
(=
)和t(
“hello”

,您的两个代码片段并不相等

在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;
}
#包括
int main()
{
char const*text=”“;//text指向包含字符串“”的内存位置
char const*s=text;//s现在指向相同的内存位置
text=“hello world”;//text现在指向另一个包含字符串“hello world”的内存位置,s继续指向字符串“”所在的内存位置
char const*t=text;//t现在指向text指向的内存位置,即包含“hello world”的位置
printf(“%s%s\n”,s,t);
返回0;
}
这将给出与Java示例相同的结果


由于Java没有指针语义,您无法实现在Java中尝试实现的功能,除非您使用某种
Holder
类来包装字符串对象。

您的两个代码片段并不相等

在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;
}
#包括
int main()
{
char const*text=”“;//text指向包含字符串“”的内存位置
char const*s=text;//s现在指向相同的内存位置
text=“hello world”;//text现在指向另一个包含字符串“hello world”的内存位置,s继续指向字符串“”所在的内存位置
char const*t=text;//t现在指向text指向的内存位置,即包含“hello world”的位置
printf(“%s%s\n”,s,t);
返回0;
}
这将给出与Java示例相同的结果


由于Java没有指针语义,您无法实现在Java中尝试实现的目标,除非您使用某种
Holder
类包装字符串对象。

Java的可能副本没有对引用的引用。它只有引用和原语。通过在调试器中单步执行每一行代码,您可以准确地看到每一行代码的作用
不会更改指向的对象
text
的某些属性,但会导致
text
指向一个全新的位置。您是否对“hello world”实际上是什么感到困惑?简单地说:Java中的“引用”更接近于C/C++中的“指针”。