在这种情况下,String =运算符引用或创建新的String对象

时间:2018-07-04 14:39:34

标签: java string object

一开始听起来可能很奇怪,看似简单,但我坚持了预期的观点。我认为在以下代码中,texts引用了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;
}

3 个答案:

答案 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中试图实现的目标。