今天來談一下java中toString這個方法。
在初學java的時候,我們學的第一個程序大概都是這樣的:
public static void main(String[] args) {
System.out.println("Hello,world!");
}
可以已經寫得不厭其煩了,哈哈,但是大家想過沒有,假如我直接輸出一個對象會怎么樣呢?
private String name;
private int age;
public Test(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Test test = new Test("張三",18);
System.out.println(test);
}
結果:com.zhang.Test@2503dbd3
乍一看,這是個啥?
實際啊,這是由於我們沒有重寫Object類的toString方法,導致它輸出的是一些古怪的字符串(該對象的內存地址)。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
通過源碼我們可以看到它是一個由類名+@符號+對象哈希碼的無符號十六進制表示組成。
getClass()是得到一個Class對象,getName()則是 得到這個類的名稱。
當我們在該類重寫toString方法之后,它的結果又不一樣了
private String name;
private int age;
@Override
public String toString() {
return "name='" + name + '\'' + ", age=" +age;
}
public Test(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Test test = new Test("張三",18);
System.out.println(test);
}
結果:name='張三', age=18
這就是重寫toString之后的好處,我們可以清晰的看到對象的屬性以及它的值。應用也十分廣泛,在平常學習中,我們常常想知道代碼的正確性以及賦值成功與否,就可以直接打印這個類,在控制台我們可以清晰的看到數據,不重寫則只是一串內存地址。
大家可能還有一個疑惑,就是為什么我沒有調用toString方法,但是他卻輸出了呢?會不會是自動調用toString方法呢?
肯定不是自動調用。答案如下:
//println方法的源碼
public void println(Object x) {
String s = String.valueOf(x);//這里調用了valueof方法
synchronized (this) {
print(s);
newLine();
}
}
//valueOf方法的源碼
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
因為Object類是所有類的父類,所以當我們傳入一個Test類的一個對象test的時候,它會自動向上轉型為Object類。下面的三目運算符可以看出來,返回的是obj.toString(),當我們沒重寫toString的時候它就會調用Object類的toString方法,也就是返回內存地址,由於Test類重寫了toString方法,所以它會調用重寫之后的toString方法,從而看到類屬性的詳細信息。
如有疑問歡迎下方留言,感謝觀看!