java 调用对象的方法_JAVA调用对象方法的执行过程
JAVA調(diào)用對(duì)象方法的執(zhí)行過程:
①.編譯器查看對(duì)象的聲明類型和方法名。假設(shè)調(diào)用x.f(parameter), ?且隱式參數(shù)x聲明為C類型的對(duì)象,有可能在C對(duì)象中存在多個(gè)參數(shù)類型和參數(shù)個(gè)數(shù)不同的f的方法{例如:f(int)、f(int,String)和f(String)},編譯器會(huì)一一列舉C類中的f方法和C的超類中聲明為public所有的f方法。
至此,編譯器已經(jīng)獲得所有可能被調(diào)用的候選方法。
②.接下來,編譯器將查看調(diào)用方法時(shí)所提供的參數(shù)類型和參數(shù)個(gè)數(shù)。如果所有名為f的方法中存在這樣一個(gè)與提供方法的參數(shù)類型和參數(shù)個(gè)數(shù)完全匹配的方法,就選擇這個(gè)方法,這個(gè)過程也稱重載解析。例如:對(duì)于調(diào)用f(“This is my java”)來說,編譯器會(huì)尋找f(String)這個(gè)方法。如果編譯器沒有找到與參數(shù)類型和參數(shù)個(gè)數(shù)匹配的方法,或者經(jīng)過類型轉(zhuǎn)換后有多個(gè)方法于此匹配,就會(huì)報(bào)告一個(gè)錯(cuò)誤。
至此,已經(jīng)尋找到需要調(diào)用的方法和參數(shù)類型
③.如果是此方法是被private、static、final修飾或則是構(gòu)造器,那么編譯器可以準(zhǔn)確的知道應(yīng)該調(diào)用哪個(gè)方法,于是便調(diào)用這個(gè)的方法。這種調(diào)用方式叫著靜態(tài)綁定。靜態(tài)綁定方式于此結(jié)束。
而與此對(duì)應(yīng)是,調(diào)用方法依賴于隱式參數(shù)的實(shí)際類型,并且在運(yùn)行時(shí)實(shí)現(xiàn)動(dòng)態(tài)綁定,編譯器采用動(dòng)態(tài)綁定的方式會(huì)生成一條調(diào)用f(String)的指令(其原因請(qǐng)查看下面的動(dòng)態(tài)綁定解析)。
④.當(dāng)程序運(yùn)行,并且采用動(dòng)態(tài)綁定調(diào)用方法時(shí),虛擬機(jī)一定調(diào)用與x所引用的對(duì)象的實(shí)際類型最適合的那個(gè)方法。假設(shè)x的實(shí)際類型是D,D是C的子類,如果D類定了方法f(String),編譯器就直接調(diào)用它,否則就在D類的超類C中尋找f(String)方法,如果C類型中不存在這個(gè)方法,則又到尋找C的超類中尋找這個(gè)方法,以此類推。這個(gè)過程就稱為動(dòng)態(tài)綁定。
動(dòng)態(tài)綁定解析:
每次調(diào)用方法時(shí)都要進(jìn)行搜索,這樣一來,時(shí)間開銷相當(dāng)大。因此,虛擬機(jī)預(yù)先為每一個(gè)類創(chuàng)建了一個(gè)方法表,其中列舉出了類中的所有方法簽名和實(shí)際調(diào)用的方法。而在真正調(diào)用方法的時(shí)候,虛擬機(jī)僅僅查找這個(gè)表就行了。在前面的列子中,虛擬機(jī)搜索D類的方法表。以便尋找與調(diào)用f(String)相匹配的方法。這個(gè)方法既可能是D.f(String),也可能是C.f(String),還有可能是*.f(String),這里的*是指D的超類。
----參考于《Core Java》
下面我們就舉一個(gè)簡(jiǎn)單的例子:
新建一個(gè)Father類,并且讓Son類繼承Father基類:
package com.bin.bind;
public class TestBind {
public static void main(String[] args) {
String name = "TOM";
String hobby = "~~~sleep~~~";
int age = 19;
Father father = new Son(name, hobby, age);
String result = father.getAllInfo();
System.out.println(result);
}
}
class Father {
public Father(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getAllInfo() {
return "姓名是:"+this.name+"\t年齡是:"+this.age;
}
private String name = null;
private int age = 0;
}
class Son extends Father {
public Son(String name, String hobby, int age) {
super(name, age);
setHobby(hobby);
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getAllInfo() {
return "姓名是:"+super.getName()+"\t年齡是:"+
super.getName()+"\t愛好是:"+hobby;
}
private String hobby = null;
}
在Father和Son類中都存在getAllInfo()這個(gè)方法,因?yàn)間etAllInfo()不是static、final、private、構(gòu)造方法,所以此方法將采用動(dòng)態(tài)綁定。
在程序執(zhí)行的時(shí)候虛擬機(jī)會(huì)為這個(gè)兩個(gè)類生成方法表
Father類:
Father(String,int)->Father(String,int)
setAge(int)->Father.setAge(int)
getAge()->Father.getAge()
setName(String)->Father.setName(String)
getName()->Father.getName()
getAllInfo()->Father.getAllInfo()
Son類:
Father(String,int)->Father(String,int)
setAge(int)->Father.setAge(int)
getAge()->Father.getAge()
setName(String)->Father.setName(String)
getName()->Father.getName()
getAllInfo()->Father.getAllInfo()
Son(String,String,age)->Son(String,String,age)
setHobby(String)->Son.setHobby(String)
getHobby()->Son.getHobby()
getAllInfo()->Son.getAllInfo()
注意:上面列舉的方法并不完整,因?yàn)樗麄冞€都默認(rèn)繼承了一個(gè)Object超類。
下面分析這條語句:
String result = father.getAllInfo();
father.getAllInfo()的解析過程如下:
①:虛擬機(jī)提取father類的實(shí)際類型的方法表。既可能是Father類也可能是Son類。(因?yàn)檫@里father引用所指向的是Son類的實(shí)例對(duì)象,所以實(shí)際類型必定是Son)
②:接下來,虛擬機(jī)搜索定義getAllInfo簽名的類,此時(shí),虛擬機(jī)已經(jīng)知道調(diào)用哪個(gè)方法。(Son中只有一個(gè)getAllInfo方法,且與此匹配,所以被調(diào)用) ③:虛擬機(jī)執(zhí)行調(diào)用方法。(最后將返回結(jié)果賦值給result)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的java 调用对象的方法_JAVA调用对象方法的执行过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: U盘怎么变成exe 给U盘变成可执行文件
- 下一篇: 微型计算机中 辅助存储器通常包括,第7章