1

It might sound strange at first, might seem simple, yet I'm stuck the well-expected point. I think in following code, text is referenced to by s and t, as output,I would get hello world hello world, but not. I get 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);
    }
}

What point did I miss until now? I'm really baffled at that. Presumably a new object is created there implicitly. But why?


Following one is not related Java, but C-knowers. I try to interpret the above code in C. I get expected result there, 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;
}
  • 5
    Possible duplicate of [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – jhamon Jul 04 '18 at 14:41
  • Java doesn't have a reference to a reference. It only has references and primitives. You can see exactly what each line of code does by stepping through it in your debugger. – Peter Lawrey Jul 04 '18 at 14:44
  • `text = "hello world";` does not change some property of the object `text` pointed to but it causes `text` to point somewhere completely new. Are you confused about what `"hello world"` actually does / is? – luk2302 Jul 04 '18 at 14:45
  • 1
    Simply speaking: A "reference" in Java is closer to what you'd call a "pointer" in C/C++. It is not at all similar to a C++ reference. – Joachim Sauer Jul 04 '18 at 14:50
  • 1
    @snr , my bad, I didn't read all 79 answers and stop to the 500+ voted ones that gives a good answer. If you know this question, you probably know the answer – jhamon Jul 04 '18 at 14:51

3 Answers3

4

I get hello world.

You should get this with two spaces at the start.

What point did I miss until now?

Using a debugger shows you why, but in short you only have references and primitives in Java. There are no references to references.

char const volatile * volatile const * xPtr = &x;

There is nothing like this available in Java.

Presumably a new object is created there implicitly.

A new StringBuilder and a new char[] are implicitly created however I don't think this is what you mean.

Stepping through the code

    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);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 3
    @snr Because there simply is no such thing as `s->text`, only `s->""` and that is it. – luk2302 Jul 04 '18 at 14:53
  • @snr there are *no references to references* in Java. `s` only points to an object it can't point to a reference to an object. What you suggest isn't available in Java, as a design decision. You only have the simplest case where a variable references an object. – Peter Lawrey Jul 04 '18 at 14:57
2

Your problem is here s = text. You think that by doing this s is a reference that will point to text (which himself point to ""). But what it does is that it evaluates the value of text and make s point to it, so s point to "" and not text.

Then when you do text = "hello"; you do not change the object "" to "hello" you just make text point to a new object (It stop pointing "" and now points "hello")

So when you print the whole things, it evaluates s (="") and t (="hello")

vincrichaud
  • 2,218
  • 17
  • 34
2

Your two code snippets are not equivalent.

You have pointers to pointers in the C example, but not in your Java example. Actually equivalent code in C would be:

#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;
}

Which will give the same result as you got in your Java example.

Since Java doesn't have pointer semantic, you cannot achieve what you tried to achieve in Java, except if you use some kind of Holder class to wrap a String object.

Max Vollmer
  • 8,412
  • 9
  • 28
  • 43
  • eventually, I made a decision towards that I don't know C too. `s` is pointer to `text` which is pointer to `""`. So, when text's pointer is changed, `s` is already pointer to `text`, final result should be text's pointing location ?? What's my wrong ?? – Soner from The Ottoman Empire Jul 04 '18 at 15:04
  • 1
    s is not a pointer to text. s is a pointer to the memory location that text pointed to before you changed what text points to in the next line. – Max Vollmer Jul 04 '18 at 15:07
  • I've updated my answer with comments describing what each pointer is pointing to in each line. Hope it makes it more clear @snr – Max Vollmer Jul 04 '18 at 15:10
  • i am not a sir - – Max Vollmer Jul 04 '18 at 15:12