為了知道靜態(tài)綁定和動態(tài)綁定的區(qū)別,我們先了解一下什么是綁定。綁定就是指引用與實際代碼之間的關(guān)聯(lián),比如說,當你引用一個變量的時候是由定義這個變量的代碼確定的。同樣的當你調(diào)用一個方法的時候,它會與這個方法的定義關(guān)聯(lián)起來。在Java里面方法綁定有兩種方式,一種叫靜態(tài)綁定,一種叫動態(tài)綁定。當一個方法被調(diào)用的時候程序?qū)嶋H的執(zhí)行和對象的創(chuàng)建有可能在編譯期確定,也可能在運行期。就像名字所說,靜態(tài)綁定有著靜態(tài)的本質(zhì),因此它發(fā)生在編譯期里,就好比根據(jù)編譯的結(jié)果你可以在代碼里清楚知道某方法的調(diào)用對應(yīng)的源碼在哪個class文件里面。
另一方面,當JVM開始執(zhí)行你的程序時動態(tài)綁定發(fā)生在運行期間。方法的調(diào)用被取決于實際的對象,這些對象的信息在編譯期里是不能得到的,因為對象的創(chuàng)建在運行期。因為在程序生命周期發(fā)生較晚,它也叫后期綁定。
那么他們最基本的不同就是一個使用變量引用類型發(fā)生在編譯期,一個使用實際對象發(fā)生在運行期。
前期綁定 vs 后期綁定
關(guān)于靜態(tài)綁定和動態(tài)綁定的區(qū)別有很多觀點,但是最重要的還是要看JVM怎么去使用。你是否有想過當有多個同名的方法的時候JVM是怎么確定要去調(diào)用哪個的?如果你知道方法重載(overloading)或者方法重寫(overriding)的話你應(yīng)該知道方法重名是怎么回事。JVM會根據(jù)靜態(tài)或動態(tài)綁定去尋找對應(yīng)的方法。
靜態(tài)和綁定的例子
在以下程序,你可以看到即使使用了靜態(tài)綁定,虛擬方法(virtual methods)并沒有綁定在編譯期,因為按我們想法會出現(xiàn)父類是會被調(diào)用的,但是事實上并不是。由于子類的方法被調(diào)用證明真實的對象在運行期被使用,因此動態(tài)綁定一般用于綁定虛擬方法。
public class Main {
public static void main(String[] args) {
// An example of static and dynamic binding in Java
Insurance current = new CarInsurance();
// dynamic binding based upon object
int premium = current.premium();
// static binding based upon class
String category = current.category();
System.out.println("premium : " + premium);
System.out.println("category : " + category);
}
class Insurance{
public static final int LOW = 100;
public int premium(){
return LOW;
}
public static String category(){
return "Insurance";
}
}
class CarInsurance extends Insurance{
public static final int HIGH = 200;
public int premium(){
return HIGH;
}
public static String category(){
return "Car Insurance";
}
}
//Output premium : 200
//category : Insurance
}
你可以看到當調(diào)用premium()方法的時候是執(zhí)行的是子類的方法,而當調(diào)用cateogry()方法的時候是執(zhí)行父類的方法。這是因為premium()是虛擬方法并且使用的是前期綁定來處理,而category()方法是一個靜態(tài)方法,在編譯期使用類名做靜態(tài)綁定來處理。
前期和后期綁定的區(qū)別總結(jié)
現(xiàn)在你知道和明白方法的調(diào)用是如何綁定的和靜態(tài)和動態(tài)的綁定是怎樣工作的(說的那么簡單我還真沒看明白),讓我們來回顧一下他們之間的一些重要的、關(guān)鍵的不同:
- 靜態(tài)綁定發(fā)生在編譯期而動態(tài)綁定發(fā)生在運行期
- 因為靜態(tài)綁定發(fā)生在程序生命周期較早階段,它也叫前期綁定。同樣動態(tài)綁定發(fā)生在程序?qū)嶋H運行中,所以也叫后期綁定。
- 靜態(tài)綁定一般用于方法重載,而動態(tài)綁定一般用于方法重寫。
- 同樣,靜態(tài)綁定可以用于私有的(private)、靜態(tài)的(static)和終態(tài)的(final)方法,因為他們不能被重寫和所有虛擬方法用動態(tài)綁定來解決。
- 真實的對象不能用于靜態(tài)綁定,相反,類型信息比如變量的類型可以用于本地的方法。另一方面,動態(tài)綁定用一個真是的對象去找到那個真正的方法的。
這里有個很好的練習是基于靜態(tài)和動態(tài)綁定的,答案是?

原文地址: Difference between early (static) binding vs late (dynamic) binding in Java