【问题标题】:String = operator references or creating new String object in this caseString = 运算符引用或在这种情况下创建新的 String 对象
【发布时间】:2018-07-04 14:39:34
【问题描述】:

一开始可能听起来很奇怪,可能看起来很简单,但我还是坚持了这一点。我认为在下面的代码中,textst 引用,作为输出,我会得到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;
}

【问题讨论】:

  • Java 没有对引用的引用。它只有引用和原语。您可以通过在调试器中单步执行每行代码来准确了解每行代码的作用。
  • text = "hello world"; 不会改变 text 指向的对象的某些属性,但它会导致 text 指向一个全新的地方。您是否对 "hello world" 实际所做的/是什么感到困惑?
  • 简单地说:Java 中的“引用”更接近于 C/C++ 中的“指针”。它与 C++ 参考完全不同。
  • @snr ,我的错,我没有阅读所有 79 个答案,而是停止了 500 多个投票给出的好答案。如果你知道这个问题,你可能就知道答案了

标签: java string object


【解决方案1】:

我打招呼世界。

你应该在开头加上两个空格。

到目前为止,我错过了什么?

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

【讨论】:

  • @snr 因为根本没有s-&gt;text 这样的东西,只有s-&gt;"" 就是这样。
  • @snr 在 Java 中没有对引用的引用s 只指向一个对象,它不能指向一个对象的引用。作为设计决策,您的建议在 Java 中不可用。您只有最简单的情况,即变量引用对象。
【解决方案2】:

您的问题在这里s = text。你认为这样做s 是一个指向text 的引用(它自己指向"")。但它的作用是评估文本的值并让s 指向它,所以s 指向"" 而不是text

然后当您执行text = "hello"; 时,您不会将对象"" 更改为"hello",您只需让text 指向一个新对象(它不再指向"",现在指向"hello"

因此,当您打印整个内容时,它会评估 s (="") 和 t (="hello")

【讨论】:

    【解决方案3】:

    你的两个代码 sn-ps 不等价。

    在 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 没有指针语义,因此您无法实现您试图在 Java 中实现的功能,除非您使用某种 Holder 类来包装 String 对象。

    【讨论】:

    • 最终,我决定我也不懂 C。 s 是指向 text 的指针,它是指向 "" 的指针。所以,当文本的指针改变时,s 已经是指向text 的指针,最终结果应该是文本的指向位置??我怎么了??
    • s 不是指向文本的指针。 s 是一个指针,指向在您更改下一行文本指向之前文本所指向的内存位置。
    • 我已经用 cmets 更新了我的答案,描述了每行中每个指针指向的内容。希望它更清楚@snr
    • 我不是先生-
    猜你喜欢
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多