国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

理解Java程序的執(zhí)行

這篇具有很好參考價值的文章主要介紹了理解Java程序的執(zhí)行。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

main 方法

public class Solution {
    public static void main(String[] args) {
        Person person = new Person();
        person.hello();
    }
}

class Person {
    public void hello() {
        System.out.println("hello");
    }
}

源文件名是 Solution.java,這是因為文件名必須與 public 類的名字相匹配。在一個源文件中,只能有一個公有類,但可以有任意數(shù)目的非公有類。

在這個示例程序中包含兩個類:Person 類和帶有 public 訪問修飾符的 Solution 類。Solution 類包含了 main 方法。

當編譯這段源代碼的時候,編譯器將在目錄下創(chuàng)建兩個 class 文件:Solution.class 和 Person.class。

將程序中包含 main 方法的類名提供給字節(jié)碼解釋器,以便啟動這個程序:java Solution。字節(jié)碼解釋器開始運行 Solution 類的 main 方法中的代碼。

理解Java程序的執(zhí)行

理解方法調(diào)用

下面假設要調(diào)用 x.f(args)。下面是調(diào)用過程的詳細描述:

  • 編譯時:
    1. 編譯器査看對象變量的聲明類型和方法名,然后獲得所有可能被調(diào)用的候選方法。
    2. 編譯器査看調(diào)用方法時提供的參數(shù)類型,然后獲得需要調(diào)用的方法名字和參數(shù)類型。
  • 運行時:
    • 如果方法是 private 方法、static 方法、final 方法或者構造器方法,那么編譯器將可以準確地知道應該調(diào)用哪個方法,我們將這種調(diào)用方式稱為靜態(tài)綁定(static binding)。與此對應的是,調(diào)用的方法依賴于對象變量 x 的實際類型,并且在運行時實現(xiàn)動態(tài)綁定。
    • 虛擬機預先為每個類創(chuàng)建了一個方法表(method table),方法表中列出了所有方法的簽名和實際調(diào)用的方法。這樣一來,在真正調(diào)用方法的時候,虛擬機僅查找方法表就行了。

1、編譯器査看對象變量的聲明類型和方法名,然后獲得所有可能被調(diào)用的候選方法。假設調(diào)用 x.f(param),且對象變量 x 被聲明為 C 類型。需要注意的是:有可能存在多個名字為 f,但參數(shù)類型不一樣的方法。例如,可能存在方法 f(int) 和方法 f(String)。編譯器將會一一列舉所有 C 類中名為 f 的方法和其父類中訪問屬性為 public 且名為 f 的方法(父類的私有方法不可訪問)。至此,編譯器已獲得所有可能被調(diào)用的候選方法。

2、接下來,編譯器將査看調(diào)用方法時提供的參數(shù)類型,然后獲得需要調(diào)用的方法名字和參數(shù)類型。如果在所有名為 f 的方法中存在一個與提供的參數(shù)類型完全匹配,就選擇這個方法。這個過程被稱為重載解析(overloading resolution)。例如,對于調(diào)用 x.f("Hello") 來說,編譯器將會挑選 f(String),而不是 f(int)。由于允許類型轉(zhuǎn)換(int 可以轉(zhuǎn)換成 double,Manager 可以轉(zhuǎn)換成 Employee 等),所以這個過程可能很復雜。如果編譯器沒有找到與參數(shù)類型匹配的方法,或者發(fā)現(xiàn)經(jīng)過類型轉(zhuǎn)換后有多個方法與之匹配,就會報告一個錯誤。至此,編譯器已獲得需要調(diào)用的方法名字和參數(shù)類型。

如果方法是 private 方法、static 方法、final 方法或者構造器方法,那么編譯器將可以準確地知道應該調(diào)用哪個方法,我們將這種調(diào)用方式稱為靜態(tài)綁定(static binding)。與此對應的是,調(diào)用的方法依賴于對象變量 x 的實際類型,并且在運行時實現(xiàn)動態(tài)綁定。在我們列舉的示例中,編譯器采用動態(tài)綁定的方式生成一條調(diào)用 f(String) 的指令。

當程序運行,并且采用動態(tài)綁定調(diào)用方法時,虛擬機一定調(diào)用與對象變量 x 所引用的對象的實際類型最合適的那個類的方法。假設 x 的實際類型是 D,D 是 C 類的子類。如果 D 類定義了 f(String) 方法,虛擬機就直接調(diào)用 D 類的 f(String) 方法;否則(D 類中沒有定義 f(String) 方法),將在 D 類的父類中尋找 f(String),以此類推。


每次調(diào)用方法都要進行搜索,時間開銷相當大。因此,虛擬機預先為每個類創(chuàng)建了一個方法表(method table),方法表中列出了所有方法的簽名(方法名、參數(shù)類型)和實際調(diào)用的方法。這樣一來,在真正調(diào)用方法的時候,虛擬機僅查找方法表就行了。

在前面的例子中,虛擬機搜索 D 類的方法表,以便尋找與調(diào)用 f(Sting) 相匹配的方法。這個方法既有可能是 D.f(String),也有可能是 C.f(String),這里的 C 是 D 的父類。這里需要提醒一點,如果調(diào)用 super.f(param),編譯器將對對象變量父類的方法表進行搜索。

方法調(diào)用的示例

public static void main(String[] args) {
    Employee e = new Manager("Carl Cracker", 80000, 1987, 12, 15);
    System.out.println("salary=" + e.getSalary());
}

現(xiàn)在,查看一下調(diào)用 e.getSalary() 的詳細過程。對象變量 e 被聲明為 Employee 類型。Employee 類只有一個名叫 getSalary() 的方法,這個方法沒有參數(shù)。因此,在這里不必擔心重載解析的問題。

由于 getSalary() 不是 private 方法、static 方法,也不是 final 方法,所以將采用動態(tài)綁定。虛擬機為 Employee 和 Manager 兩個類生成方法表。


在 Employee 的方法表中,列出了這個類定義的方法。實際上,下面列出的方法并不完整,Employee 類有一個父類 Object,Employee 類從這個父類中還繼承了許多方法,在此我們略去了 Object 的方法。

Employee:
    getName() -> Employee.getName()
    getSalary() -> Employee.getSalary()
    getHireDay() -> Employee.getHireDay()
    raiseSalary(double) -> Employee.raiseSalary(doubl e)

Manager 的方法表稍微有些不同。其中有三個方法是繼承而來的,一個方法是重新定義的(方法的重寫),還有一個方法是新增加的。

Manager:
    getName() -> Employee.getName()
    getSalary() -> Manager.getSalary()
    getHireDay() -> Employee.getHireDay()
    raiseSalary(double) -> Employee.raiseSalary(doubl e)
    setBonus(double) -> Manager.setBonus(double)

在運行時,調(diào)用 e.getSalary() 的解析過程為:

  1. 首先,虛擬機提取對象變量 e 的實際類型的方法表。既可能是 Employee、Manager 的方法表,也可能是 Employee 類的其他子類的方法表。
  2. 接下來,虛擬機搜索對象變量 e 的實際類型的方法表。此時,虛擬機已經(jīng)知道應該調(diào)用哪個方法。
  3. 最后,虛擬機調(diào)用方法。

動態(tài)綁定有一個非常重要的特性:無需對現(xiàn)存的代碼進行修改,就可以對程序進行擴展。假設增加一個新類 Executive,并且對象變量 e 有可能引用這個類的對象,我們不需要對包含調(diào)用 e.getSalary() 的代碼進行重新編譯。如果 e 恰好引用一個 Executive 類的對象,就會自動地調(diào)用 Executive.getSalary() 方法。

參考資料

《Java核心技術卷一:基礎知識》(第10版)第 5 章:繼承 5.1.6 理解方法調(diào)用文章來源地址http://www.zghlxwxcb.cn/news/detail-421351.html

到了這里,關于理解Java程序的執(zhí)行的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Java項目計算程序執(zhí)行時間方法

    優(yōu)點: 1、spring自帶工具類,可直接使用 2、代碼實現(xiàn)簡單,使用更簡單 3、統(tǒng)一歸納,展示每項任務耗時與占用總時間的百分比,展示結(jié)果直觀 4、性能消耗相對較小,并且最大程度的保證了start與stop之間的時間記錄的準確性 5、可在start時直接指定任務名字,從而更加直觀的

    2024年02月20日
    瀏覽(14)
  • java程序啟動時自動執(zhí)行方法 @PostConstruct,單元測試@Test

    java程序啟動時自動執(zhí)行方法,在方法上添加@PostConstruct注解即可,可以代替單元測試junit的@Test注解 @PostConstruct //程序啟動時自動執(zhí)行方法 @Test //需要選中該方法運行啟動(單元測試) java 代碼----程序啟動時自動執(zhí)行方法 @PostConstruct java 代碼----需要選中該方法運行啟動(單元

    2024年02月05日
    瀏覽(22)
  • 《深入理解Java虛擬機》讀書筆記:Class類文件的結(jié)構

    《深入理解Java虛擬機》讀書筆記:Class類文件的結(jié)構

    Class類文件的結(jié)構 ? Sun公司以及其他虛擬機提供商發(fā)布了許多可以運行在各種不同平臺上的虛擬機,這些虛擬機都可以載入和執(zhí)行同一種平臺無關的的程序存儲格式——字節(jié)碼(ByteCode),從而實現(xiàn)了程序的“一次編寫,到處運行”。 ? Java虛擬機提供的語言無關性 ? “Clas

    2024年02月13日
    瀏覽(18)
  • class_13:靜態(tài)成員static關鍵字

    class_13:靜態(tài)成員static關鍵字

    ? ? ?

    2024年01月20日
    瀏覽(29)
  • Java面試題Class類的理解?創(chuàng)建類的對象的方式?

    Java面試題Class類的理解?創(chuàng)建類的對象的方式?

    1.類的加載過程: 程序經(jīng)過 javac.exe 命令以后,會生成一個或多個字節(jié)碼文件(.class結(jié)尾)。 接著我們使用 java.exe 命令對某個字節(jié)碼文件進行解釋運行。相當于將某個字節(jié)碼文件 加載到內(nèi)存中。此過程就稱為類的加載 。加載到內(nèi)存中的類,我們就稱為運行時類,此運行時類,

    2024年02月10日
    瀏覽(19)
  • ChatGPT還是有點東西的-public static <T> List<T> Arrays.asList(T... a) {...}

    業(yè)務開發(fā)需要判斷業(yè)務狀態(tài)是否在30、40、50、60的集合內(nèi),所以寫了以下代碼 自我Review代碼時,驗證了下這行代碼,發(fā)現(xiàn)狀態(tài)為30時,仍然返回false。 在自我懷疑中調(diào)整代碼,并驗證,代碼如下: 沒想很明白,于是問了下ChatGPT。 Arrays.asList() 方法返回的結(jié)果類型取決于傳入的

    2024年02月12日
    瀏覽(16)
  • 第08章_面向?qū)ο缶幊蹋ǜ呒墸?static,單例設計模式,理解mian方法,代碼塊,final,抽象類與抽象方法,接口,內(nèi)部類,枚舉類,注解,包裝類)

    第08章_面向?qū)ο缶幊蹋ǜ呒墸?static,單例設計模式,理解mian方法,代碼塊,final,抽象類與抽象方法,接口,內(nèi)部類,枚舉類,注解,包裝類)

    回顧類中的實例變量(即非static的成員變量) 創(chuàng)建兩個Circle對象: Circle類中的變量radius是一個實例變量(instance variable),它屬于類的每一個對象,c1中的radius變化不會影響c2的radius,反之亦然。 如果想讓一個成員變量被類的所有實例所共享,就用static修飾即可,稱為類變量(

    2024年01月25日
    瀏覽(21)
  • Java 中的 static:靜態(tài)變量、靜態(tài)方法,一切都在掌握中

    ??:你只管努力,剩下的交給時間 ?? :小破站 static ,這個小小的在Java中扮演著重要的角色,但它的用途和工作原理可能會讓人感到困惑。你是否曾想過為什么有些方法和變量可以直接從類訪問,而無需創(chuàng)建實例?或者為什么某些變量在多個實例之間共享相同的值?

    2024年02月04日
    瀏覽(23)
  • 45從零開始學Java之詳解static修飾符、靜態(tài)變量和靜態(tài)方法

    作者 :孫玉昌,昵稱【 一一哥 】,另外【 壹壹哥 】也是我哦 千鋒教育高級教研員、CSDN博客專家、萬粉博主、阿里云專家博主、掘金優(yōu)質(zhì)作者 在前一篇文章中, 壹哥 給大家講解了abstract,從而我們掌握了抽象類與抽象方法的特性。除此之外,面向?qū)ο蟮暮诵男揎椃?/p>

    2024年02月09日
    瀏覽(20)
  • 深入理解python虛擬機:程序執(zhí)行的載體——棧幀

    深入理解python虛擬機:程序執(zhí)行的載體——棧幀

    棧幀(Stack Frame)是 Python 虛擬機中程序執(zhí)行的載體之一,也是 Python 中的一種執(zhí)行上下文。每當 Python 執(zhí)行一個函數(shù)或方法時,都會創(chuàng)建一個棧幀來表示當前的函數(shù)調(diào)用,并將其壓入一個稱為調(diào)用棧(Call Stack)的數(shù)據(jù)結(jié)構中。調(diào)用棧是一個后進先出(LIFO)的數(shù)據(jù)結(jié)構,用于管

    2023年04月25日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包