<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
目錄結構圖
a. 疑問
有些讀者會問,方法的執行不是取決於程式碼設定中的執行物件嗎?為什麼還要選擇呢?
b. 回答
Java
中的特性:多型,即重寫 & 過載。下面我會詳細講解。先看下面的程式碼
public class Test { static abstract class Human { } static class Man extends Human { } static class Woman extends Human { } // 執行程式碼 public static void main(String[] args) { Human man = new Man(); // 變數man的靜態型別 = 參照型別 = Human:不會被改變、在編譯器可知 // 變數man的動態型別 = 範例物件型別 = Man:會變化、在執行期才可知 } }
即:
下面,我將詳細講解Java
中的分派型別:靜態分派 & 動態分派
定義: 根據 變數的靜態型別 進行方法分派 的 行為
Java
虛擬機器器來執行應用場景: 方法過載(OverLoad
)
範例說明
public class Test { // 類定義 static abstract class Human { } // 繼承自抽象類Human static class Man extends Human { } static class Woman extends Human { } // 可供過載的方法 public void sayHello(Human guy) { System.out.println("hello,guy!"); } public void sayHello(Man guy) { System.out.println("hello gentleman!"); } public void sayHello(Woman guy) { System.out.println("hello lady!"); } // 測試程式碼 public static void main(String[] args) { Human man = new Man(); Human woman = new Woman(); Test test = new Test(); test.sayHello(man); test.sayHello(woman); } } // 執行結果 hello,guy! hello,guy!
根據上述的講解,大家應該明白執行結果的原因:
OverLoad
) = 靜態分派 = 根據 變數的靜態型別 確定執行(過載)哪個方法man
、woman
)的靜態型別(Human
)確定過載sayHello()
中引數為Human guy
的方法,即sayHello(Human guy)
特別注意
可通過 強制型別轉換 改變 變數的靜態型別
Human man = new Man(); test.sayHello((Man)man); // 強制型別轉換 // 此時man的靜態型別從 Human 變為 Man // 所以會呼叫sayHello()中引數為Man guy的方法,即sayHello(Man guy)
問題描述:
範例說明
public class Overload { private static void sayHello(char arg){ System.out.println("hello char"); } private static void sayHello(Object arg){ System.out.println("hello Object"); } private static void sayHello(int arg){ System.out.println("hello int"); } private static void sayHello(long arg){ System.out.println("hello long"); } // 測試程式碼 public static void main(String[] args) { sayHello('a'); } } // 執行結果 hello char
因為‘a’
是一個char
型別資料(即靜態型別是char
),所以會選擇引數型別為char
的過載方法。
若註釋掉sayHello(char arg)
方法,那麼會輸出
hello int
因為‘a’
除了可代表字串,還可代表數位97。因此當沒有最合適的sayHello(char arg)
方式進行過載時,會選擇第二合適(第二優先順序)的方法過載,即 sayHello(int arg)
總結:當沒有最合適的方法進行過載時,會選優先順序第二高的的方法進行過載,如此類推。
優先順序順序為:
char>int>long>float>double>Character>Serializable>Object>...
其中...
為變長引數,將其視為一個陣列元素。變長引數的過載優先順序最低。
因為 char
轉型到 byte
或 short
的過程是不安全的,所以不會選擇引數型別為byte
或 short
的方法進行過載,故優先順序列表裡也沒有。
特別注意
注意只跟其編譯時型別(即靜態型別)相關
即根據 變數的動態型別 確定執行哪個方法
Override
)// 定義類 class Human { public void sayHello(){ System.out.println("Human say hello"); } } // 繼承自 抽象類Human 並 重寫sayHello() class Man extends Human { @Override protected void sayHello() { System.out.println("man say hello"); } } class Woman extends Human { @Override protected void sayHello() { System.out.println("woman say hello"); } } // 測試程式碼 public static void main(String[] args) { // 情況1 Human man = new man(); man.sayHello(); // 情況2 man = new Woman(); man.sayHello(); } } // 執行結果 man say hello woman say hello // 原因解析 // 1. 方法重寫(Override) = 動態分派 = 根據 變數的動態型別 確定執行(重寫)哪個方法 // 2. 對於情況1:根據變數(Man)的動態型別(man)確定呼叫man中的重寫方法sayHello() // 3. 對於情況2:根據變數(Man)的動態型別(woman)確定呼叫woman中的重寫方法sayHello()
特別注意
對於程式碼中:
Human man = new Man(); man = new Woman(); man.sayHello(); // man稱為執行sayHello()方法的所有者,即接受者。
invokevirtual
指令執行的第一步 = 確定接受者的實際型別invokevirtual
指令執行的第二步 = 將 常數池中 類方法符號參照 解析到不同的直接參照上第二步即方法重寫(Override
)的本質
本文全面講解方法分派的型別 & 過程,更多關於java JVM靜態動態分派模型的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45