最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM 方法調(diào)用之動(dòng)態(tài)分派(詳解)

 更新時(shí)間:2017年05月01日 09:15:42   投稿:jingxian  
下面小編就為大家?guī)?lái)一篇JVM 方法調(diào)用之動(dòng)態(tài)分派(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

1. 動(dòng)態(tài)分派

一個(gè)體現(xiàn)是重寫(xiě)(override)。下面的代碼,運(yùn)行結(jié)果很明顯。

public class App {
 
 public static void main(String[] args) {
  Super object = new Sub();
  object.f();
 }
}

 class Super {
 public void f() {
  System.out.println("super : f()");
 }
 
 public void f(int i) {
  System.out.println("super : f(int)");
 }
}

class Sub extends Super{
 
 @Override
 public void f() {
  System.out.println("sub : f()");
 }
 
 @Override
 public void f(int i) {
  System.out.println("sub : f(int)");
 }
 
 public void f(char c) {
  System.out.println("sub : f(char)");
 }
}

最終輸出sub : f();

那么虛擬機(jī)是怎么做到動(dòng)態(tài)分派的呢?

不同的虛擬機(jī)有不同的實(shí)現(xiàn),最常用的是使用虛方法表(Virtual Method Table)

2. 虛方法表

對(duì)于Super和Sub類(lèi),虛方法表大致如下:(靈魂畫(huà)師)

上面的靈魂畫(huà)作是什么意思呢?

虛方法表中存放著各個(gè)方法的實(shí)際入口地址。如果某個(gè)方法在子類(lèi)中沒(méi)有被重寫(xiě),那子類(lèi)的虛方法表里面的地址入口和父類(lèi)相同簽名的方法的地址入口是一致的,都指向父類(lèi)的實(shí)現(xiàn)入口。如果子類(lèi)中重寫(xiě)了這個(gè)方法,子類(lèi)方法表中的地址將會(huì)替換為向子類(lèi)實(shí)現(xiàn)版本的入口地址。

從上圖主要得出幾個(gè)信息:

a. 上圖的大部分方法,子類(lèi)Super和Sub均沒(méi)有重寫(xiě),那么都指向父類(lèi)Object的類(lèi)型數(shù)據(jù)。f()和f(int)方法,父類(lèi)子類(lèi)都實(shí)現(xiàn)了,那么兩者就指向不同的實(shí)現(xiàn)地址。f(char)只在子類(lèi)定義實(shí)現(xiàn),自然指向子類(lèi)的類(lèi)型數(shù)據(jù)。

b. 為了程序?qū)崿F(xiàn)上的方便,具有相同簽名的方法,在父類(lèi),子類(lèi)的虛方法表中都應(yīng)當(dāng)具有一樣的索引序號(hào),這樣當(dāng)類(lèi)型變換時(shí),僅需要變更查找的方法表,就可以從不同的虛方法表中按索引轉(zhuǎn)換出所需要的入口地址。

3. 實(shí)例分析

以本文開(kāi)頭的代碼進(jìn)行分析。通過(guò)javap命令查看main方法的指令。

其中的invokevirtual指令詳細(xì)調(diào)用過(guò)程是這樣的:

1)指令中的#19指的是App類(lèi)的常量池中第19個(gè)常量表的索引項(xiàng)。這個(gè)常量表(CONSTATN_Methodref_info)記錄的是方法f()信息的符號(hào)引用,JVM首先根據(jù)這個(gè)符號(hào)引用找到調(diào)用方法f()的類(lèi)的全限定名com.khlin.Super,這是因?yàn)樽兞縪bject被聲明為Super類(lèi)型。

2) 在Super類(lèi)型的方法表中查找方法f(),如果找到,則將方法f()在方法表中的索引項(xiàng)(具體值我不了解,這里將其記為index) 記錄到App類(lèi)的常量池中第19個(gè)常量表中(常量池解析)。因此,如果Super類(lèi)型方法表中沒(méi)有f(),那么即使Sub類(lèi)型的方法表有該方法,也會(huì)報(bào)編譯失敗。

3)在調(diào)用invokevirtual指令前有一個(gè)aload_1指令,它會(huì)將開(kāi)始創(chuàng)建中堆中的Sub對(duì)象的引用壓入操作數(shù)棧。然后invokevirtual指令會(huì)根據(jù)這個(gè)Sub對(duì)象的引用首先找到堆中的Sub對(duì)象,然后進(jìn)一步找到Sub對(duì)象所屬類(lèi)型的方法表。

4)這時(shí),通過(guò)2)查找的index,可以定位到Sub類(lèi)型方法表中的f()方法,然后通過(guò)直接地址找到該方法字節(jié)碼所在的內(nèi)存空間。這就是父類(lèi)和子類(lèi)相同簽名的方法索引序號(hào)一致的用處。

4. 綜合考慮:一個(gè)可能想錯(cuò)的例子

將本文開(kāi)頭的代碼里的main方法稍作修改,調(diào)用其他的方法。

public static void main(String[] args) {
   Super object = new Sub();
   char c = 'a';
   object.f(c);
  }

結(jié)果將輸出sub : f(int)

明明Sub方法里有完全一樣類(lèi)型的f(char)方法,卻調(diào)用的是f(int).

相信通過(guò)前面的學(xué)習(xí),已經(jīng)可以明白原因了。

在object.f(c)調(diào)用時(shí),虛擬機(jī)先到Super類(lèi)的方法表里,查找最為合適的方法。

Super類(lèi)里沒(méi)有剛好參數(shù)為char的f(char)方法,按照前面靜態(tài)分派和參數(shù)類(lèi)型自動(dòng)轉(zhuǎn)換的學(xué)習(xí),可以知道,編譯器使用了除了f(char)之外最為合適的方法f(int)。獲取到索引后,通過(guò)索引到實(shí)際對(duì)象的Sub方法表里找到f(int)方法,最終執(zhí)行的就是Sub類(lèi)的f(int)方法。

該方法的字節(jié)碼指令證明了上述的論證。

以上這篇JVM 方法調(diào)用之動(dòng)態(tài)分派(詳解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring中的BeanFactory與FactoryBean的講解

    spring中的BeanFactory與FactoryBean的講解

    今天小編就為大家分享一篇關(guān)于spring中的BeanFactory與FactoryBean的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • Java中的裝箱和拆箱深入理解

    Java中的裝箱和拆箱深入理解

    裝箱和拆箱是java中老生常談的問(wèn)題,下面小編通過(guò)本文給大家介紹java裝箱和拆箱最基本的東西,感興趣的朋友一起看下吧
    2016-07-07
  • 淺談Spring中IOC的理解和認(rèn)知

    淺談Spring中IOC的理解和認(rèn)知

    這篇文章主要介紹了淺談Spring中IOC的理解和認(rèn)知,想了解Spring的同學(xué)不要錯(cuò)過(guò)啊
    2021-04-04
  • Spring Boot中的JdbcTemplate是什么及用法小結(jié)

    Spring Boot中的JdbcTemplate是什么及用法小結(jié)

    Spring Boot中的JdbcTemplate是一個(gè)強(qiáng)大的數(shù)據(jù)庫(kù)訪問(wèn)工具,它簡(jiǎn)化了數(shù)據(jù)庫(kù)操作的過(guò)程,在本文中,我們了解了JdbcTemplate的基本概念,并演示了如何在Spring Boot應(yīng)用程序中使用它,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • Java中的Graphics2D類(lèi)基本使用教程

    Java中的Graphics2D類(lèi)基本使用教程

    這篇文章主要介紹了Java中的Graphics2D類(lèi)基本使用教程,Graphics2D類(lèi)較之Graphics類(lèi)中的功能更加專(zhuān)業(yè),需要的朋友可以參考下
    2015-10-10
  • java實(shí)現(xiàn)定制數(shù)據(jù)透視表的示例詳解

    java實(shí)現(xiàn)定制數(shù)據(jù)透視表的示例詳解

    數(shù)據(jù)透視表(Pivot?Table)是一種數(shù)據(jù)分析工具,通常用于對(duì)大量數(shù)據(jù)進(jìn)行匯總、分析和展示,本文主要介紹了如何使用Java將計(jì)算項(xiàng)添加到數(shù)據(jù)透視表中,感興趣的可以了解下
    2023-12-12
  • 關(guān)于Java中Comparable 和 Comparator的用法

    關(guān)于Java中Comparable 和 Comparator的用法

    這篇文章主要介紹了關(guān)于Java中Comparable 和 Comparator的用法,Comparable 和 Comparator 是關(guān)于排序的兩個(gè)接口,用來(lái)實(shí)現(xiàn) Java 集合中的的排序功能,需要的朋友可以參考下
    2023-04-04
  • SpringCloud通過(guò)MDC實(shí)現(xiàn)分布式鏈路追蹤

    SpringCloud通過(guò)MDC實(shí)現(xiàn)分布式鏈路追蹤

    在DDD領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中,我們使用SpringCloud來(lái)去實(shí)現(xiàn),但排查錯(cuò)誤的時(shí)候,通常會(huì)想到Skywalking,但是引入一個(gè)新的服務(wù),增加了系統(tǒng)消耗和管理學(xué)習(xí)成本,對(duì)于大型項(xiàng)目比較適合,但是小的項(xiàng)目顯得太過(guò)臃腫了,所以本文介紹了SpringCloud通過(guò)MDC實(shí)現(xiàn)分布式鏈路追蹤
    2024-11-11
  • 詳解Java CompletableFuture使用方法以及與FutureTask的區(qū)別

    詳解Java CompletableFuture使用方法以及與FutureTask的區(qū)別

    CompletableFuture實(shí)現(xiàn)了CompletionStage接口和Future接口,前者是對(duì)后者的一個(gè)擴(kuò)展,增加了異步回調(diào)、流式處理、多個(gè)Future組合處理的能力,使Java在處理多任務(wù)的協(xié)同工作時(shí)更加順暢便利
    2021-10-10
  • Javaweb基礎(chǔ)入門(mén)requse原理與使用

    Javaweb基礎(chǔ)入門(mén)requse原理與使用

    Request對(duì)象的作用是與客戶(hù)端交互,收集客戶(hù)端的Form、Cookies、超鏈接,或者收集服務(wù)器端的環(huán)境變量,接下來(lái)本篇將詳細(xì)講述
    2021-11-11

最新評(píng)論

宁化县| 安泽县| 金沙县| 鄂州市| 抚宁县| 安泽县| 顺义区| 苗栗县| 泰和县| 清镇市| 钟山县| 梁河县| 内丘县| 溧阳市| 苗栗县| 安阳县| 金华市| 咸阳市| 故城县| 体育| 乌审旗| 平顶山市| 娄底市| 东辽县| 肇庆市| 东丽区| 成安县| 黄陵县| 腾冲县| 炎陵县| 黄陵县| 宝鸡市| 铜鼓县| 云霄县| 富阳市| 寿宁县| 安阳市| 临潭县| 莆田市| 大埔县| 罗甸县|