當前位置:才華齋>計算機>java語言>

Java中靜態繫結和動態繫結的區別

java語言 閱讀(1.88W)

一個Java程式的執行要經過編譯和執行(解釋)這兩個步驟,同時Java又是面向物件的程式語言。當子類和父類存在同一個方法,子類重寫了父類的方法,程式在執行時呼叫方法是呼叫父類的方法還是子類的重寫方法呢,這應該是我們在初學Java時遇到的問題。這裡首先我們將確定這種呼叫何種方法實現或者變數的操作叫做繫結。

Java中靜態繫結和動態繫結的區別

在Java中存在兩種繫結方式,一種為靜態繫結,又稱作早期繫結。另一種就是動態繫結,亦稱為後期繫結。

  程式繫結的概念:

繫結指的是一個方法的呼叫與方法所在的類(方法主體)關聯起來。對java來說,繫結分為靜態繫結和動態繫結;或者叫做前期繫結和後期繫結

靜態繫結(早繫結 編譯器繫結):

在程式執行前方法已經被繫結,此時由編譯器或其它連線程式實現。例如:C 。針對java可以理解為程式編譯期的繫結;特別說明一點,java當中的方法只有final,static,private和構造方法是前期繫結

動態繫結(遲繫結 執行期繫結):

後期繫結:在執行時根據具體物件的型別進行繫結。

若一種語言實現了後期繫結,同時必須提供一些機制在執行期間判斷物件的型別,並分別呼叫適當的方法。也就是說編譯器此時依然不知道物件的型別,但方法呼叫機制能自己去調查,找到正確的方法主體。不同的語言對後期繫結的實現方法是有所區別的。可以這樣認為:它們都要在物件中安插某些特殊型別的資訊。

  動態繫結的過程:

虛擬機器提取物件的實際型別的方法表 虛擬機器搜尋方法簽名 呼叫方法

關於繫結相關的總結:

瞭解三者的概念之後,我們發現java屬於後期繫結。在java中,幾乎所有的方法都是後期繫結,在執行時動態繫結方法屬於子類還是基類。但也有特殊,針對static方法和final方法由於不能被繼承,因此在編譯時就可以確定他們的值,他們是屬於前期繫結。特別說明的一點,private宣告的方法和成員變數不能被子類繼承,所有的private方法都被隱式的指定為final的(由此我們知道:將方法宣告為final型別的. 一是為了防止方法被覆蓋,二是為了有效的關閉java中的動態繫結)。java中的後期繫結是由JVM來實現的,我們不用去顯式的宣告它,而C++則不同,必須明確的宣告某個方法具備後期繫結。java當中的向上轉型或者說多型是藉助於動態繫結實現的,所以理解動態繫結,也就搞定向上轉型和多型。

對於java當中的方法而言,除了final,static,private和構造方法是前期繫結外,其他的方法全部為動態繫結。而動態繫結的典型發生在父類和子類的轉換宣告之下:

比如:Parent p = new Children();

具體過程如下:

1、編譯器檢查物件的宣告型別和方法名。假設我們呼叫x.f(args)方法,並且x已經被宣告為C類的物件,那麼編譯器會列舉出C類中所有的名稱為f的方法和從C類的超類繼承過來的f方法

2、接下來編譯器檢查方法呼叫中提供的引數型別。如果在所有名稱為f 的方法中有一個引數型別和呼叫提供的引數型別最為匹配,那麼就呼叫這個方法,這個過程叫做“過載解析

3、當程式執行並且使用動態繫結呼叫方法時,虛擬機器必須呼叫同x所指向的物件的實際型別相匹配的方法版本。假設實際型別為D(C的子類),如果D類定義了f(String)那麼該方法被呼叫,否則就在D的超類中搜尋方法f(String),依次類推

問題思考:

如何提供給方法使用者一個方法,來完成一個任務。如果使用者有特殊要求又要可以定製自己的方法?

涉及知識:

子父類,介面,向上轉型,動態繫結

具體程式碼:

package gxuyuanzhilu;public interface MyInterfaces { void doting();}package gxuyuanzhilu;public class Drink implements MyInterfaces { @Override public void doting() { tln("我在喝水"); }}package gxuyuanzhilu;public class Eat implements MyInterfaces { @Override public void doting() { tln("我在吃東西"); }}package gxuyuanzhilu;public class Run implements MyInterfaces { @Override public void doting() { tln("我在奔跑"); }}package gxuyuanzhilu;public class TestDynamicBind { public static void main(String[] args) { MyInterfaces my = null; my = new Eat(); bind(my); my = new Drink(); bind(my); my = new Run(); bind(my); } static void bind(MyInterfaces my){ ng(); }}

以上就是本文的全部內容,希望對大家的學習有所幫助。