2013-02-18 51 views
0

我已經減少了一組類文件作爲OO的例子。他們完美地工作,但我不明白,從WorkerTest.javaprintln呼叫如何使它一路過關斬將Worker.javaDate.java?這兩個Worker.javaDate.javatoString方法,但都沒有明確調用,但我可以從輸出告訴我們都使用。這些方法如何被使用而不被調用?

這是如何工作,或我應該研究什麼概念?

public class WorkerTest { 
    public static void main(String[] args) { 
     Date birth = new Date(7, 15, 1922); 
     Worker worker = new Worker(birth); 

     System.out.println(worker); 
    } 
} 

public class Worker { 
    private Date birthday; 

    public Worker( Date inboundBirthday) { 
     birthday = inboundBirthday; 
    } 

    public String toString() { 
     return String.format("Birthday: %s", birthday); 
    } 
} 

public class Date { 

    private int month; 
    private int day; 
    private int year; 

    public Date(int inboundMonth, int inboundDay, int inboundYear) { 
     month = inboundMonth; 
     day = inboundDay; 
     year = inboundYear; 
    } 

    public String toString() { 
     return String.format("%d/%d/%d", month, day, year); 
    } 
}  

輸出: Birthday: 7/15/1922

+2

我確定其他人可以更好地描述它,但是,如果您正在編寫的值不是'String',Java將自動在'Object'上調用'toString'。 – MadProgrammer 2013-02-18 04:21:34

+1

相關問題:http://stackoverflow.com/questions/8555771/why-is-the-tostring-method-being-called-when-i-print-an-object – ajp15243 2013-02-18 04:21:57

回答

4

當println遇到一個變量時,它會嘗試確定它應該如何打印。它檢查是否覆蓋了相關類的t​​oString()方法。因此,發生了什麼事情:println需要打印類worker的實例,因此它會檢查Worker類中的toString()方法。在工人類裏面,它發現這條線:

return String.format("Birthday: %s", birthday); 

現在它必須弄清楚如何打印生日。由於生日是Date的一個實例,它會檢查Date的toString()方法。理解這一切的關鍵是Java的內置類也有toString()方法,你只是看不到它們。這是一個很好的例子,因爲它可以告訴你幕後發生了什麼。

+0

因爲Object有'toString'方法「檢查是否有toString()方法」是一個「小」的錯誤...雖然答案的要點是正確的)+1 – MadProgrammer 2013-02-18 04:35:16

+0

@MadProgrammer這是一個很好的觀點!我試圖保持它儘可能簡單,但我編輯它是更準確:) – 2013-02-18 04:38:11

+1

也許,「檢查,看看是否有任何'toString()** **重寫**」聽起來會更好。 – SudoRahul 2013-02-18 04:41:32

9

PrintStream.println(obj)電話obj.toString()。 (或者更確切地說:它調用String.valueOf(obj),進而調用obj.toString()除非obj爲空引用。)

the Javadoc for java.io.PrintStream

(也許你錯過的是,toString實際上是java.lang.ObjectWorkerDate的方法僅僅是覆蓋它。所以所有對象有方法和JDK方法可以依靠它的存在。見the Javadoc for `java.lang.Object爲所有對象都具有的所有方法的列表。)