String = оператор ссылки или создание нового объекта String в этом случае - PullRequest
0 голосов
/ 04 июля 2018

Поначалу это может звучать странно, может показаться простым, но я застрял в ожидаемой точке. Я думаю, что в следующем коде на 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;
}

Ответы [ 3 ]

0 голосов
/ 04 июля 2018

Ваша проблема здесь s = text. Вы думаете, что при этом s является ссылкой, которая будет указывать на text (который сам указывает на ""). Но он вычисляет значение текста и заставляет s указывать на него, поэтому s указывает на "", а не text.

Затем, когда вы делаете text = "hello";, вы не изменяете объект "" на "hello", вы просто заставляете text указывать на новый объект (он перестает указывать "", а теперь указывает "hello")

Таким образом, когда вы печатаете все, он оценивает s (= "") и t (= "hello")

0 голосов
/ 04 июля 2018

Ваши два фрагмента кода не эквивалентны.

У вас есть указатели на указатели в примере 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.

0 голосов
/ 04 июля 2018

Привет, мир.

Вы должны получить это с двумя пробелами в начале.

Какой момент я упустил до сих пор?

Использование отладчика показывает, почему, но вкратце у вас есть только ссылки и примитивы в 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...