关于System.out.println()方法与String类的toString()方法

public class ToStringTest {
    public static void main(String[] args) {
       ToStringTest t = new ToStringTest();
        System.out.println(t);
    }

    @Override
    public String toString() {
        return "ToStringTest{AAAAA}";
    }
}

如上代码,如果问会输出什么,一定会回答:ToStringTest{AAAAA}
。如果进一步问为什么,大多数都会说因为println方法会调用toString方法,我们又重写了该方法,所以会返回我们自定义的字符串。

   String s = "fff";
   System.out.println(s);

上面两行同理会输出fff,但是当点击String类的toString()方法时,会看到如下代码:

  public String toString() {
        return this;
    }

这里返回的是this,如果你会有,这里返回的是this,一个String的对象,为什么在控制台打出的是字符(String类维护的char[])?那么下面会给你答案。

原因是println方法会调用toString方法,我们又重写了该方法,所以会返回我们自定义的字符串,这句话只对了一半,因为println方法里面是调用了toString()方法,但不是只调用了此方法。

进入println方法,代码如下:

public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);/* 进入这个方法*/
            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;
        }
    }
public void write(String str) throws IOException {
        write(str, 0, str.length());/* 进入这个方法*/
    }
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 {  
                cbuf = new char[len];
            }
            str.getChars(off, (off + len), cbuf, 0);/* 进入这个方法*/
            write(cbuf, 0, len);
        }
    }
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);/*这里的数组赋值方法第一个参数value就是String维护的char[]数组,里面就是字符串的具体值*/
    }

toString的调用在一开始,回到一开始的println方法

public void println(Object x) {
        String s = String.valueOf(x);/* 进入这个方法*/
        synchronized (this) {
            print(s);
            newLine();
        }
    }
public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }//这里传的不是null的话,会根据多态调用自己重写的toString()方法,返回自定义的字符串对象

由上面的分析,总结来说,在使用println方法打印时,如果重写了toString()方法,会根据多态调用自己的toString()方法,返回自定义的字符串对象,并在后续中取出此Stirng对象维护的char[]的值并打印,我们平时说的println方法会调用toString方法,我们又重写了该方法,所以会返回我们自定义的字符串,其实只说了一半,并不是直接将toString()返回的类容“放”到控制台,如果不理解可能会带来一些误解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值