Java的引用變量有兩個類型,一個是編譯時類型,一個是運行時類型,編譯時類型由聲明該變量時使用的類型決定,運行時類型由實際賦給該變量的對象決定。若是編譯時類型和運行時類型不一致,會出現所謂的多態。由於子類實際上是一種特殊的父類,所以java容許把一個子類對象直接賦值給一個父類引用變量,無須任何類型轉換,或者被稱爲向上轉型,由系統自動完成。java
引用變量在編譯階段只能調用其編譯時類型所具備的方法,但運行時則執行它運行時類型所具備的方法,所以,編寫Java代碼時,引用變量只能調用聲明該變量所用類裏包含的方法。與方法不一樣的是,對象的屬性則不具有多態性。經過引用變量來訪問其包含的實例屬性時,系統老是試圖訪問它編譯時類所定義的屬性,而不是它運行時所定義的屬性。對象
所謂的編譯期,就是將Java代碼編譯成.class文件的過程,該過程只涉及到語法句法的正確與否,不涉及內存方面及執行方面的檢查。
所謂的運行期,就是Java虛擬機執行.class文件的過程。該過程會涉及到內存調用。實際類型檢查等方面。內存
關於動態綁定,在調用該引用實例的方法的時候,會優先去調用該實例引用的運行時方法,也就是實際類型的方法。而在調用該引用實例的成員變量的時候,會優先去調用該實例應用的編譯時的成員變量,也就是聲明的類型的成員變量。對於,調用引用實例的方法,在編譯時,是調用聲明類型的成員方法(多態的實現原理),也就是所謂的編譯時類型的方法,而到了運行時,調用的是實際的類型的成員方法,也就是所謂的運行時類型的方法。而對於調用引用實例的成員變量,在編譯時,便是調用聲明類型的成員變量,在運行時更是調用聲明類型的成員變量,也就時說,對於調用引用實例的成員變量,不管是編譯時仍是運行時,均是調用編譯時類型的成員變量。虛擬機