[轉載] Java靜態綁定與動態綁定

參考鏈接: Java中的靜態綁定與動態綁定

程序綁定的概念:

?

綁定指的是一個方法的調用與方法所在的類(方法主體)關聯起來。對java來說,綁定分為靜態綁定和動態綁定;或者叫做前期綁定和后期綁定.

?

?靜態綁定:

?

在程序執行前方法已經被綁定(也就是說在編譯過程中就已經知道這個方法到底是哪個類中的方法),此時由

編譯器或其它連接程序實現。例如:C。

?針對java簡單的可以理解為程序編譯期的綁定;這里特別說明一點,java當中的方法只有final,static,private和構造方法是前期綁定

?

?動態綁定:

?后期綁定:

在運行時根據具體對象的類型進行綁定。

?若一種語言實現了后期綁定,同時必須提供一些機制,可在運行期間判斷對象的類型,并分別調用適當的方法。也就是說,

編譯器此時依然不知道對象的類型,但方法調用機制能自己去調查,找到正確的方法主體。不同的語言對后期綁定的實現方法是有所區別的。但我們至少可以這樣認為:它們都要在對象中安插某些特殊類型的信息。

?動態綁定的過程:

?

虛擬機提取對象的實際類型的方法表;虛擬機搜索方法簽名;調用方法。?

?

關于final,static,private和構造方法是前期綁定的理解 對于private的方法,首先一點它不能被繼承,既然不能被繼承那么就沒辦法通過它子類的對象來調用,而只能通過這個類自身的對象來調用。因此就可以說private方法和定義這個方法的類綁定在了一起。 final方法雖然可以被繼承,但不能被重寫(覆蓋),雖然子類對象可以調用,但是調用的都是父類中所定義的那個final方法,(由此我們可以知道將方法聲明為final類型,一是為了防止方法被覆蓋,二是為了有效地關閉java中的動態綁定)。 構造方法也是不能被繼承的(網上也有說子類無條件地繼承父類的無參數構造函數作為自己的構造函數,不過個人認為這個說法不太恰當,因為我們知道子類是通過super()來調用父類的無參構造方法,來完成對父類的初始化, 而我們使用從父類繼承過來的方法是不用這樣做的,因此不應該說子類繼承了父類的構造方法),因此編譯時也可以知道這個構造方法到底是屬于哪個類。 對于static方法,具體的原理我也說不太清。不過根據網上的資料和我自己做的實驗可以得出結論:static方法可以被子類繼承,但是不能被子類重寫(覆蓋),但是可以被子類隱藏。(這里意思是說如果父類里有一個static方法,它的子類里如果沒有對應的方法,那么當子類對象調用這個方法時就會使用父類中的方法。而如果子類中定義了相同的方法,則會調用子類的中定義的方法。唯一的不同就是,當子類對象上轉型為父類對象時,不論子類中有沒有定義這個靜態方法,該對象都會使用父類中的靜態方法。因此這里說靜態方法可以被隱藏而不能被覆蓋。這與子類隱藏父類中的成員變量是一樣的。隱藏和覆蓋的區別在于,子類對象轉換成父類對象后,能夠訪問父類被隱藏的變量和方法,而不能訪問父類被覆蓋的方法)

?由上面我們可以得出結論,如果一個方法不可被繼承或者繼承后不可被覆蓋,那么這個方法就采用的靜態綁定。

?

?java的編譯與運行

?java的編譯過程是將java源文件編譯成字節碼(jvm可執行代碼,即.class文件)的過程,在這個過程中java是不與內存打交道的,在這個過程中編譯器會進行語法的分析,如果語法不正確就會報錯。

?Java的運行過程是指jvm(java虛擬機)裝載字節碼文件并解釋執行。在這個過程才是真正的創立內存布局,執行java程序。

?java字節碼的執行有兩種方式: (1)即時編譯方式:解釋器先將字節編譯成機器碼,然后再執行該機器碼;(2)解釋執行方式:解釋器通過每次解釋并執行一小段代碼來完成java字節碼程序的所有操作。(這里我們可以看出java程序在執行過程中其實是進行了兩次轉換,先轉成字節碼再轉換成機器碼。這也正是java能一次編譯,到處運行的原因。在不同的平臺上裝上對應的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),依次類推。 JAVA 虛擬機調用一個類方法時(靜態方法),它會基于對象引用的類型(通常在編譯時可知)來選擇所調用的方法。相反,當虛擬機調用一個實例方法時,它會基于對象實際的類型(只能在運行時得知)來選擇所調用的方法,這就是動態綁定,是多態的一種。動態綁定為解決實際的業務問題提供了很大的靈活性,是一種非常優美的機制。

?

?與方法不同,在處理java類中的成員變量(實例變量和類變量)時,并不是采用運行時綁定,而是一般意義上的靜態綁定。所以在向上轉型的情況下,對象的方法可以找到子類,而對象的屬性(成員變量)還是父類的屬性(子類對父類成員變量的隱藏)。

?Java代碼?

?

public class Father {

? ? protected String name = "父親屬性";

}

  

?

public class Son extends Father {

? ? protected String name = "兒子屬性";

?

? ? public static void main(String[] args) {

? ? ? ? Father sample = new Son();

? ? ? ? System.out.println("調用的屬性:" + sample.name);

? ? }

}

?結論,調用的成員為父親的屬性。

?這個結果表明,子類的對象(由父類的引用handle)調用到的是父類的成員變量。

所以必須明確,運行時(動態)綁定針對的范疇只是對象的方法。

?現在試圖調用子類的成員變量name,該怎么做?最簡單的辦法是

將該成員變量封裝成方法getter形式。

?代碼如下:

?Java代碼?

?

public class Father {

? ? protected String name = "父親屬性";

?

? ? public String getName() {

? ? ? ? return name;

? ? }

}  

?

public class Son extends Father {

? ? protected String name = "兒子屬性";

?

? ? public String getName() {

? ? ? ? return name;

? ? }

?

? ? public static void main(String[] args) {

? ? ? ? Father sample = new Son();

? ? ? ? System.out.println("調用的屬性:" + sample.getName());

? ? }

}

?結果:調用的是兒子的屬性

?

java因為什么對屬性要采取靜態的綁定方法。這是因為靜態綁定是有很多的好處,它可以讓我們在編譯期就發現程序中的錯誤,而不是在運行期。這樣就可以提高程序的運行效率!而對方法采取動態綁定是為了實現多態,多態是java的一大特色。多態也是面向對象的關鍵技術之一,所以java是以效率為代價來實現多態這是很值得的。

?

?注:以上內容大部分來自互聯網,小部分是個人見解,絕非權威性言論。如有語言表達不當或者表述不正確的地方,萬望指教。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540292.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540292.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540292.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于批量插入數據之我見(100萬級別的數據,mysql)

2019獨角獸企業重金招聘Python工程師標準>>> 因前段時間去面試,問到如何高效向數據庫插入10萬條記錄,之前沒處理過類似問題,也沒看過相關資料,結果沒答上來,今天就查了些資料,總結出三種方法&am…

各個OS關于查看磁盤和wwn號的方法

1,HP-UX幾個命令1)查看型號,和uname -a差不多model2)查看光纖卡信息ioscan -funC fc3) 查看掃描出的磁盤信息ioscan -fucC disk4)查看磁盤及其對應的路徑ioscan -m dsf5) 查看劃分過來的lunioscan -m lun6) 查看磁盤大小diskinfo …

[轉載] Java是不是面向對象的程序

參考鏈接: 為什么Java不是純粹的面向對象語言 轉載自:https://blog.csdn.net/a21700790yan/article/details/80129053 Java——是否確實的 “純面向對象”?讓我們深入到Java的世界,試圖來證實它。 在我剛開始學習 Java 的前面幾…

極速理解設計模式系列:6.適配器模式(Adapter Pattern)

四個角色:目標抽象類角色(Target)、目標對象角色(Adapter)、源對象角色(Adaptee)、客戶端角色(Client) 目標抽象類角色(Target):定義需要實現的目標接口 目標對象角色(Adapter):調用另外一個源對象,并且轉換…

[轉載] Java之繼承

參考鏈接: Java多重繼承 Java之繼承 繼承是面向對象程序的一個基本特征,通過繼承可以實現父子關系,以及代碼的復用。通過繼承實現的類稱為子類,被繼承的類稱為父類,所有直接或間接被繼承的類都稱為父類。 Java類體…

Spark(二): 內存管理

2019獨角獸企業重金招聘Python工程師標準>>> Spark 作為一個以擅長內存計算為優勢的計算引擎,內存管理方案是其非常重要的模塊; Spark的內存可以大體歸為兩類:execution和storage,前者包括shuffles、joins、sorts和agg…

[轉載] 手把手教你整合最優雅SSM框架:SpringMVC + Spring + MyBatis

參考鏈接: Java繼承類的對象創建 本文發表于2016年6月,寫于作者學生時期。文中使用到的技術和框架可能不是當下最佳實踐,甚至很不“優雅”。但對于剛接觸JavaEE和Spring的同學來說,還是能有很多收獲的,大牛輕拍 我們…

多播、組播、廣播優缺點分析

2019獨角獸企業重金招聘Python工程師標準>>> 單播、多播和廣播單播”(Unicast)、“多播”(Multicast)和“廣播”(Broadcast)這三個術語都是用來描述網絡節點之間通訊方式的術語。那么這些術語究…

[轉載] Java重載、覆蓋與構造函數

參考鏈接: Java中的繼承和構造函數 /** * 拷貝構造函數---Copyf t2 new Copyf(t1);就不會在調用默認構造函數了。 * 復制clone和引用 * 重載是在同一個類(范圍)中,覆蓋是子類對父類而言。 重載不關心返回值類型。 靜態方法不能被…

LOFTERD18B542F16FF685FD684F427B4…

2019獨角獸企業重金招聘Python工程師標準>>> 驗證 轉載于:https://my.oschina.net/jinhengyu/blog/1572124

[轉載] Java獲取一個類繼承的父類或者實現的接口的泛型參數

參考鏈接&#xff1a; Java中的接口和繼承 泛型的作用就不多介紹了&#xff0c;如果你想具備架構設計能力&#xff0c;那么熟練使用泛型是必不可少的。 不多說了&#xff0c;先定義泛型父類和泛型接口&#xff1a; package cn.zhh; public class Parent<T1, T2> { …

PHP系列(一)PHP流程控制結構

while(){} do{ }while(); for( 表達式1; 表達式2;表達式3 ){ 語句或語句序列; } if(){} if(){ }elseif{} <?php $i0; while(true) { if($i>100) break; echo ".$i.<br>"; $i; } ?> <?php echo "<table border1800>"; echo &quo…

[轉載] Scala繼承與Java的區別

參考鏈接&#xff1a; Java中將final與繼承一起使用 在之前的筆記Java靜態屬性和方法的繼承問題中&#xff0c;通過具體的實驗證明&#xff0c;在子類中重寫父類的字段時并沒有覆蓋父類的字段&#xff0c;只是隱藏了父類的字段。而在scala中則不同&#xff0c;scala子類的同名…

Source Map調試壓縮后代碼

在前端開發過程中&#xff0c;無論是樣式還是腳本&#xff0c;運行時的文件可能是壓縮后的&#xff0c;那這個時候調試起來就很麻煩。 這個時候&#xff0c;可以使用Source Map文件來優化調試&#xff0c;Source Map是一個信息文件&#xff0c;里面儲存著原代碼位置信息&#x…

[轉載] Python3十大經典錯誤及解決辦法

參考鏈接&#xff1a; Python中的關鍵字2 ◆ ◆ ◆ ◆ ◆ 接觸了很多Python愛好者&#xff0c;有初學者&#xff0c;亦有轉行人。不論大家學習Python的目的是什么&#xff0c;總之&#xff0c;學習Python前期寫出來的代碼不報錯就是極好的。下面&#xff0c;嚴小樣兒為大家羅…

兩臺電腦間大量數據拷貝的快捷方法

可能大家會遇到需要將一臺電腦里的數據拷貝到另外一臺電腦&#xff0c;最常用的方法是用u盤或移動硬盤等存儲設備來拷貝&#xff0c;這樣速度慢&#xff0c;而且可能拷貝多次才能將數據拷貝完。現提供一種方法&#xff0c;就是通過windows 的文件共享來實現。通過千兆網線直接連…

[轉載] 使用 Web 標準生成 ASP.NET 2.0 Web 站點

參考鏈接&#xff1a; 使用super訪問Java祖父母的成員 Stephen WaltherSuperExpert.com 適用于&#xff1a; Microsoft ASP.NET 2.0 (Beta 2) Microsoft Visual Studio .NET 2005 Microsoft Visual Web Developer 摘要&#xff1a; Microsoft ASP.NET 2.0 具有很多有用的功能…

Office快捷鍵大全之三(Access快捷鍵下篇)

向下鍵 向某幫助主題的末尾滾動 Page Up 以較大增量向某幫助主題的開頭滾動 Page Down 以較大增量向某幫助主題的末尾滾動 Home 移到某幫助主題的開頭 End 移到某幫助主題的末尾 CtrlP 打印當前幫助主題 CtrlA 選定整個幫助主題 CtrlC 將選定項復制到"剪貼…

[轉載] 如何在Android設備之間共享Google Play應用,音樂等

參考鏈接&#xff1a; 使用super訪問Java祖父母的成員 We recently showed you how to configure your iOS devices for app and media sharing; more than a few people wrote in asking how to do the same thing with Google Play purchases. Read on as we dig into how t…

linux 高性能讀書筆記之通用socket地址

####socket網絡編程接口 socket的地址是結構體sockaddr 代碼如下 struct sockaddr{ sa_family_t sa_family; char sa_data[14]; } sa_family 成員是地址族類型&#xff08;sa_family_t)變量。地址族類型通常與協議族類型對應 1.二者對應表 協議族地址表描述PF_UNIXAF_UNIXUNIX本…