午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java中為什么this可以調(diào)用當(dāng)前實(shí)例

瀏覽:17日期:2022-08-08 17:28:44
目錄1. 前言2. 棧幀3. 分析4. 總結(jié)1. 前言

在剛開(kāi)始學(xué)習(xí)Java的時(shí)候,大家肯定都接觸過(guò)this關(guān)鍵字,尤其是在構(gòu)造函數(shù)賦值的時(shí)候,如下示例:

public class Person { private String name; private int age; public Person(String name, int age) { // 必須加this關(guān)鍵字,否則無(wú)法完成成員變量的賦值 this.name = name; this.age = age; }}

在構(gòu)造函數(shù)中,如果成員變量名稱和參數(shù)名稱相同時(shí),必須加this關(guān)鍵字,否則你只是將參數(shù)name賦值給它本身,并沒(méi)有賦值給Person.name,因?yàn)榫植孔兞康膬?yōu)先級(jí)高于成員變量。一旦加上this關(guān)鍵字,由于this指向的是當(dāng)前實(shí)例,就可以完成對(duì)象的成員變量賦值。

那為什么可以通過(guò)this關(guān)鍵字訪問(wèn)到當(dāng)前對(duì)象呢?

2. 棧幀

要弄清這個(gè)問(wèn)題,首先要了解JVM在執(zhí)行方法時(shí),方法棧的棧幀結(jié)構(gòu)。

Java虛擬機(jī)以【方法】作為最基本的運(yùn)行單元,【棧幀】就是用于支持JVM進(jìn)行方法調(diào)用背后的數(shù)據(jù)結(jié)構(gòu),它也是JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)中【虛擬機(jī)棧】中的棧元素。

簡(jiǎn)單點(diǎn)說(shuō),方法的執(zhí)行過(guò)程可看作是一個(gè)個(gè)棧幀從入棧到出棧的過(guò)程。

棧幀中存儲(chǔ)了方法的:局部變量表、操作數(shù)棧、動(dòng)態(tài)連接和方法返回地址等信息。

Java中為什么this可以調(diào)用當(dāng)前實(shí)例

當(dāng)使用javac程序?qū)⒃创a編譯成字節(jié)碼后,一個(gè)方法的棧幀需要多大的局部變量表,多深的操作數(shù)棧就已經(jīng)被計(jì)算出來(lái),并且寫(xiě)入到方法表的【Code】屬性中了,這一切和程序運(yùn)行時(shí)無(wú)關(guān)。

換言之,一個(gè)方法它有多少個(gè)局部變量,在編譯時(shí)就已經(jīng)確定,不會(huì)隨著程序的運(yùn)行而改變。今天我們要探究的【this】問(wèn)題,就在方法棧的局部變量表中。

3. 分析

我們?nèi)匀挥胘avap命令來(lái)分析編譯后的Class文件,這是最有說(shuō)服力的。

public class Person { public void say() { } public static void staticSay() { }}

如上一段代碼,分別有一個(gè)實(shí)例方法和靜態(tài)方法,我們已經(jīng)知道,在靜態(tài)方法中,是無(wú)法訪問(wèn)【this】的,但是在實(shí)例方法中可以。

先javac Person.java再javap -verbose Person,得到的信息有點(diǎn)長(zhǎng),我只貼這兩個(gè)方法的信息。

public void say();descriptor: ()Vflags: ACC_PUBLICCode: stack=0, locals=1, args_size=1 0: return LineNumberTable: line 8: 0public static void staticSay();descriptor: ()Vflags: ACC_PUBLIC, ACC_STATICCode: stack=0, locals=0, args_size=0 0: return LineNumberTable: line 12: 0

重點(diǎn)關(guān)注【Code】那一欄,say()有一個(gè)局部變量,有一個(gè)參數(shù)。staticSay()沒(méi)有局部變量,也沒(méi)有參數(shù)。

是不是感到很疑惑?say()方法形參是空的,方法體也是空的,為什么編譯后會(huì)顯示它有一個(gè)局部變量和一個(gè)形參呢?

其實(shí),對(duì)于實(shí)例方法而言,它至少有一個(gè)參數(shù)和一個(gè)局部變量,那就是當(dāng)前對(duì)象。JVM在調(diào)用對(duì)象的實(shí)例方法時(shí),會(huì)將對(duì)象本身的引用作為第0號(hào)參數(shù)傳遞過(guò)去,這樣你就可以通過(guò)this關(guān)鍵字訪問(wèn)到對(duì)象本身了,其實(shí)也就是訪問(wèn)第0個(gè)參數(shù)而已。

如下,這兩個(gè)方法其實(shí)是等價(jià)的。

public void say(Person this, String text) { System.out.println(text);}public void say(String text) { System.out.println(text);}4. 總結(jié)

Java虛擬機(jī)在執(zhí)行方法時(shí),會(huì)將方法打包成一個(gè)【棧幀】,棧幀中有【局部變量表】,參數(shù)也是局部變量表的一部分,一個(gè)方法的局部變量表有多大在編譯時(shí)就已經(jīng)確定,不會(huì)隨著程序的運(yùn)行而改變。對(duì)于實(shí)例方法而言,在編譯時(shí)會(huì)自動(dòng)加上一個(gè)隱藏的0號(hào)參數(shù),就是當(dāng)前類。JVM在調(diào)用對(duì)象的實(shí)例方法時(shí),會(huì)自動(dòng)將對(duì)象引用作為第0號(hào)參數(shù)傳遞過(guò)去,訪問(wèn)【this】其實(shí)就是訪問(wèn)第0號(hào)參數(shù)。

到此這篇關(guān)于Java中為什么this可以調(diào)用當(dāng)前實(shí)例的文章就介紹到這了,更多相關(guān)Java this調(diào)用內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 午夜合集 | 男女性动态图 | 在线观看中文字幕视频 | 91操视频| 农村少妇久久久久久久 | av一起草| 色姑娘av| 欧美成人精品在线观看 | av国产一区 | 在线观看中文字幕 | 黄色动漫在线免费观看 | 成年人观看 | 黄色片网站视频 | 亚洲午夜久久久 | 国产一区二区三区三州 | 国产成人精品自拍 | 成人短片| 亚洲a在线播放 | 亚洲国产清纯 | 国产一区二区免费 | 国产中文字幕在线播放 | 亚洲精品18p| 久久人人爽人人爽人人片 | 亚洲23p| 国产午夜一区二区三区 | 久久色在线 | 51国产偷自视频区视频 | 天天爽天天操 | 国产草草影院 | 日韩字幕在线观看 | 午夜私人影院在线观看 | 性涩av| 成人av在线影院 | 波多野吉衣一区二区 | 日韩中文字幕av在线 | 91免费国产在线 | a级黄色免费视频 | 深爱五月激情五月 | 亚洲91av | 日韩av成人网 | 成人在线毛片 |