-1

The overridden code of toString() in java.lang.String is as follows:

public String toString(){
return this;
}

So,printing a String reference variable should print address of reference variable(because toString() returns 'this') but not a String literal.Why am I wrong?

For Example, consider the code

class Sample
{
String s="dummy";
System.out.println(s);//implicit call to toString()
}

According to the logic in source code of toString(), address of (variable)s should be printed while output is "dummy".Why is this happening?

  • 1
    toString returns String object. Word `this` refers to String object. – Coderino Javarino Jul 05 '16 at 06:47
  • 2
    There isn't an implicit call to `toString`. The overload of `println` which is being called is this one: https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#println-java.lang.String- Which takes a string directly, and prints each char in it. – Will Jul 05 '16 at 06:48

3 Answers3

5

Look at the System.out.println code, it is not using toString but it writes a char[] which is retrieved from String:

public void write(String str, int off, int len) throws IOException {
    synchronized (lock) {
        char cbuf[];
        if (len <= WRITE_BUFFER_SIZE) {
            if (writeBuffer == null) {
                writeBuffer = new char[WRITE_BUFFER_SIZE];
            }
            cbuf = writeBuffer;
        } else {    // Don't permanently allocate very large buffers.
            cbuf = new char[len];
        }
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
    }
}

The call stack of println before the above method (which is in Writer):

PrintStream:

public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

private void write(String s) {
    try {
        synchronized (this) {
            ensureOpen();
            textOut.write(s);
            textOut.flushBuffer();
            charOut.flushBuffer();
            if (autoFlush && (s.indexOf('\n') >= 0))
                out.flush();
        }
    }
    catch (InterruptedIOException x) {
        Thread.currentThread().interrupt();
    }
    catch (IOException x) {
        trouble = true;
    }
}

Writer:

public void write(String str) throws IOException {
    write(str, 0, str.length());
}
Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
4

First, there no implicit call to toString in this code:

String s="dummy";
System.out.println(s); // <== No implicit call to toString()

s is a String, so System.out.println(String) is called; no toString occurs.

The reason that the string's contents are output is that System.out.println(String) is designed to print the contents of the string.

printing a String reference variable should print address of reference variable(because toString() returns 'this')

No. The reason you see java.lang.Object@15db9742 or similar when calling toString on some objects is that the implementation of toString in Object returns a string in that form (note: it's not the address of the object). But classes like String override toString to return more useful strings, and of course in the case of String, the most useful string toString can return is the string itself.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

toString() is supposed to return a string representation of any objects (thus it exists on java.lang.Object).

When called on a string object, the string representation of that string is guess what ... the string itself; therefore toString() returns the string itself.

GhostCat
  • 137,827
  • 25
  • 176
  • 248