日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理

發(fā)布時(shí)間:2024/10/8 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

知道的越多,不知道的就越多,業(yè)余的像一棵小草!

編輯:業(yè)余草

來(lái)源:https://www.xttblog.com/?p=5028

B 站:業(yè)余草

最近一個(gè)粉絲加我說(shuō),接到了阿里的面試,問(wèn)問(wèn)我阿里會(huì)面試哪方面的東西。我說(shuō),阿里的套路基本上是,你會(huì)什么就問(wèn)你什么,直到問(wèn)得你懷疑人生。正所謂,你知道的越多,不知道的就越多,業(yè)余的像一顆小草!

今天,我們就一起來(lái)討論一個(gè)這個(gè)網(wǎng)友遇到的阿里面試題,Java 中 this 和 super 關(guān)鍵字的底層實(shí)現(xiàn)原理!文章后面附了一個(gè)我錄制的視頻,大家忽略!

眾所周知,在 Java 中,this 具有以下含義。

  • 在 Java 中,每當(dāng)一個(gè)對(duì)象創(chuàng)建后,Java 虛擬機(jī)都會(huì)給這個(gè)對(duì)象分配一個(gè)指向自身的引用,也就是 this。同時(shí)如果對(duì)象是子類對(duì)象,則還會(huì)有一個(gè) super 引用指向當(dāng)前對(duì)象的父類對(duì)象。
  • 在類的方法定義中使用 this 關(guān)鍵字,表示使用該方法的對(duì)象的引用。
  • 在一個(gè)類中,this 可以表示該類的當(dāng)前實(shí)例。
  • this 是對(duì)當(dāng)前類對(duì)象的引用,對(duì)象只有被實(shí)例化才存在。

根據(jù) this 的這些含義,面試官就想知道 this 是怎么出來(lái)的?先看下面的代碼。

public?class?Xttblog?{
????private?String?name;

????public?void?setName(String?name){
????????this.name?=?name;
????}

????public?static?void?main(String[]?args)?{
????????Xttblog?xttblog?=?new?Xttblog();
????????xttblog.setName("業(yè)余草");
????}
}

在 setName 方法中,可以使用 this 的本質(zhì)是:編譯器在調(diào)用某個(gè)實(shí)例方法時(shí),實(shí)際上會(huì)把當(dāng)前的實(shí)例對(duì)象的引用作為第一個(gè)參數(shù)傳遞給方法。

經(jīng)過(guò)編譯器的處理,xttblog.setName(“業(yè)余草”) 這行代碼實(shí)際上變成 xttblog.setName(xttblog,”業(yè)余草”)。而如果想從方法內(nèi)部獲取當(dāng)前對(duì)象的引用,就有一個(gè)專門的關(guān)鍵字 this,表示“調(diào)用方法的那個(gè)對(duì)象”的引用(如 xttblog)。

這一點(diǎn),我能想到有 3 種方法來(lái)驗(yàn)證它。

第一種是我們通過(guò) Bytecode 工具查看字節(jié)碼的時(shí)候,會(huì)發(fā)現(xiàn)有 setName 方法有兩個(gè) LOCALVARIABLE,即兩個(gè)局部變量,一個(gè)是 String 的,一個(gè)是 Xttblog 對(duì)象。

OCALVARIABLE?args?[Ljava/lang/String;?L0?L3?0
LOCALVARIABLE?xttblog?Lcom/xttblog/Xttblog;?L1?L3?1

第二種就更簡(jiǎn)單了,我們給 setName 方法在第一位再加一個(gè) Xttblog this 參數(shù),你會(huì)發(fā)現(xiàn)編譯器不會(huì)報(bào)錯(cuò),方法調(diào)用都能夠成功。

public?class?Xttblog?{
????private?String?name;

????public?void?setName(Xttblog?this,String?name){
????????this.name?=?name;
????}

????public?static?void?main(String[]?args)?{
????????Xttblog?xttblog?=?new?Xttblog();
????????xttblog.setName("業(yè)余草");
????}
}

第三種驗(yàn)證方法,我們借助 Java8 提供的函數(shù)接口來(lái)驗(yàn)證。比如下面的代碼。

public?class?Xttblog?{
????private?String?name?=?"業(yè)余草";
????private?String?sayStr;

????public?void?setName(String?name){
????????this.name?=?name;
????}

????private?String?say(String?sayStr){
????????this.sayStr?=?sayStr;
????????return?this.name?+?"?say?:?"?+?this.sayStr;
????}

????public?static?void?main(String[]?args)?{
????????Xttblog?xttblog?=?new?Xttblog();
????????xttblog.setName("業(yè)余草");

????????BiFunction?function?=?Xttblog::say;
????????String?str?=?function.apply(xttblog,?"hello~");
????????System.out.println(str);
????}
}

以 BiFunction 為例,它要求的是以兩個(gè)輸入?yún)?shù),一個(gè)輸出參數(shù)。而我們調(diào)用的 say 只需要一個(gè)字符串類型的輸入?yún)?shù),但是我們的示例代碼中,卻傳遞了兩個(gè)參數(shù)。一個(gè)是 Xttblog 類型,一個(gè)是 String 類型,編譯器沒(méi)有報(bào)錯(cuò),可以正常執(zhí)行。

這也驗(yàn)證了 this 的底層實(shí)現(xiàn)原理。

同理,super 的本質(zhì)是:當(dāng)我們 new 一個(gè)子類對(duì)象的時(shí)候,子類除了生成一個(gè) this 引用指向自身,還會(huì)生成一個(gè)指向其直接父類對(duì)象的引用 super。如果子類在繼承父類的非私有的法和成員變量時(shí),沒(méi)有同名的方法和變量,可以直接通過(guò)名稱使用父類的方法和變量。如果子類存在與父類同名的方法和成員變量時(shí),要想?yún)^(qū)別訪問(wèn)父類和自身的變量和方法,需要使用 super 關(guān)鍵字調(diào)用父類的方法和屬性。

這些在字節(jié)碼中都有體現(xiàn)。以下面的代碼為例:

public?class?Codedq?extends?Xttblog{
????private?String?skill;

????public?void?setSkill(String?skill){
????????this.skill?=?skill;
????????System.out.println(super.say("hello?world"));
????????System.out.println(super.getName()?+?"會(huì):"?+?this.skill);
????}
}

我們?cè)谧止?jié)碼中會(huì)看到,在 Codedq 的構(gòu)造函數(shù)中,調(diào)用了父類 init 方法。

public?()V
???L0
????LINENUMBER?9?L0
????ALOAD?0
????INVOKESPECIAL?com/xttblog/Xttblog.?()V
????RETURN
???L1
????LOCALVARIABLE?this?Lcom/xttblog/Codedq;?L0?L1?0
????MAXSTACK?=?1
????MAXLOCALS?=?1

注意上面的 INVOKESPECIAL 指令。super 關(guān)鍵字的底層原理就是靠 INVOKESPECIAL 指令。

在 Codedq 的代碼中,super 就是靠 INVOKESPECIAL 指令來(lái)調(diào)用父類方法的。

invokespecial 指令的主要作用是,用于調(diào)用一些需要特殊處理的實(shí)例方法,包括實(shí)例初始化方法、私有方法和父類方法。(Invoke instance method; special handling for superclass, private, and instance initialization method invocations )。

最后,我們來(lái)個(gè)簡(jiǎn)單的總結(jié),this 的底層實(shí)現(xiàn)是默認(rèn)傳值,super 是靠 INVOKESPECIAL 指令。

?

以上內(nèi)容,若有疑問(wèn),歡迎公眾號(hào)評(píng)論區(qū)留言指正!

?

總結(jié)

以上是生活随笔為你收集整理的java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。