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()返回的类容“放”到控制台,如果不理解可能会带来一些误解。