子類對(duì)象是包含整個(gè)父類對(duì)象仍是僅僅擁有父類對(duì)象的引用庶喜?

1.問(wèn)題描述:

子類對(duì)象是包含整個(gè)父類對(duì)象仍是僅僅擁有父類對(duì)象的引用小腊?
個(gè)人描述:擴(kuò)展類的實(shí)例對(duì)象在內(nèi)存中包含的是基類的一個(gè)實(shí)例還是實(shí)例的引用?

2.問(wèn)題解釋:

首先,這個(gè)問(wèn)題有一個(gè)假設(shè):任意一個(gè)類的實(shí)例必定至少有一個(gè)或多個(gè)對(duì)象組成;
第二久窟,其結(jié)構(gòu)方式類似于列表(包含基類對(duì)象)或者鏈表(持有引用);
總結(jié),擴(kuò)展類對(duì)象與基類對(duì)象的關(guān)系就是 ExtendsClassObj has a BaseClassObj

3.個(gè)人回答:

首先秩冈,類的擴(kuò)展關(guān)系和基類實(shí)例與擴(kuò)展類實(shí)例的關(guān)系是不具有相關(guān)性的,類的擴(kuò)展目的在于代碼的復(fù)用,而擴(kuò)展類的對(duì)象與基類的對(duì)象之間沒有任何關(guān)系(除非擴(kuò)展類顯式的聲明擴(kuò)展類對(duì)象持有一個(gè)基類對(duì)象的引用)斥扛。
所以擴(kuò)展類實(shí)例化并不會(huì)實(shí)例化一個(gè)基類的對(duì)象入问,但是會(huì)加載基類并對(duì)基類初始化,原因很簡(jiǎn)單:需要復(fù)用基類的屬性和方法稀颁。
第二芬失,擴(kuò)展類實(shí)例在進(jìn)行實(shí)例方法調(diào)用或者對(duì)實(shí)例屬性讀寫(方法或者屬性來(lái)自于基類)的時(shí),如果ExtendsClass沒有重寫B(tài)aseClass的方法,那么是不會(huì)包含BaseClass的方法信息(可以javap -c ExtendsClass 反編譯字節(jié)碼),那么他是怎么執(zhí)行的呢峻村?每個(gè)類在JVM內(nèi)有自己的Class(Java用于描述類的類)對(duì)象(這個(gè)class對(duì)象里邊有所屬父類索引信息,自己的方法表,屬性表等信息):在方法執(zhí)行的時(shí)候麸折,會(huì)首先檢測(cè)引用的類型再檢測(cè)其所指向?qū)ο蟮膶?shí)際類型(Base base = new ExtendsBase()或者BaseExtends baseExtends = new BaseExtends())1,如果方法在擴(kuò)展類的方法區(qū)里找到就執(zhí)行擴(kuò)展類的,2,如果在擴(kuò)展類的方法中沒有找到就會(huì)自動(dòng)尋找它的基類的方法區(qū)3,重復(fù)1/2步驟;
tip: JVM對(duì)于靜態(tài)方法和實(shí)力方法的invoke指令有區(qū)分粘昨,分別為invokestatic和invokevirtual垢啼;

4.關(guān)于this(aload_0)和super:

tip1:this指代當(dāng)前線程操作的本類實(shí)例窜锯。由編譯器在后臺(tái)默認(rèn)的的加在形參列表第一個(gè)位置上) obj.test(Object...objs) 可以理解為Class.test(obj,..objs) 在方法內(nèi)用this指代obj(由JVM aload_0 載入);
tip2芭析;super指代基類鏈表锚扎,super.getClass().getName()可以翻譯為:從基類鏈的各自的方法區(qū)找到getClass()方法(Object final的不可被重寫)然后執(zhí)行,返回Class對(duì)象再getName();

//源代碼:
public class Base {
    private String name;

    public Base() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Base(String aname) {
        super();
        name = aname;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Base getInstance(){
        return this;
    }
    public static void test(Base base,String s,int i){
        System.out.println("test Base");
    }
}
//反編譯:
Compiled from "Base.java"
public class oop.Base {
  public oop.Base();
    Code:
       0: aload_0  //將在本類construtor前的全部局部變量壓入棧頂(this) 請(qǐng)注意getInstance方法的反編譯
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: return

  public oop.Base(java.lang.String);
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: aload_1  //構(gòu)造參數(shù)壓入棧頂
       6: putfield      #17                 // Field name:Ljava/lang/String;
       9: return

  public java.lang.String getName();
    Code:
       0: aload_0
       1: getfield      #17                 // Field name:Ljava/lang/String;
       4: areturn

  public void setName(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #17                 // Field name:Ljava/lang/String;
       5: return

  public oop.Base getInstance();
    Code:
       0: aload_0
       1: areturn

  public static void test(oop.Base, java.lang.String, int);
    Code:
       0: getstatic     #27                 // Field java/lang/System.out:Ljava/io/PrintStream; 獲取靜態(tài)方法 
       3: ldc           #33                 // String test Base 載入字符串
       5: invokevirtual #35                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V執(zhí)行實(shí)例方法
       8: return
}
//源代碼:
public class BaseExtends extends Base{
    private String sex;
    public BaseExtends() {
        super();
        sex = "ChildSex";
    }

    public BaseExtends(String asex) {
        super();
        sex = asex;
    }
    public BaseExtends(String aname,String asex) {
        super(aname);
        sex = asex;
    }
    public String getSex() {
        return sex;
    }

    public void setSex(String asex) {
        sex = asex;
        super.getName();
    }
    public void test(String s){
        String str = sex;
    }
    public static void test(Base base ,String s,int i){
        System.out.println("test BaseExtends");
    }
}
//反編譯
public class oop.BaseExtends extends oop.Base {
  public oop.BaseExtends();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method oop/Base."<init>":()V  在執(zhí)行基類的初始化代碼
       4: aload_0 
       5: ldc           #12                 // String ChildSex
       7: putfield      #14                 // Field sex:Ljava/lang/String;
      10: return 

  public oop.BaseExtends(java.lang.String);
    Code:
       0: aload_0
       1: invokespecial #10                 // Method oop/Base."<init>":()V
       4: aload_0
       5: aload_1
       6: putfield      #14                 // Field sex:Ljava/lang/String;
       9: return

  public oop.BaseExtends(java.lang.String, java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #23                 // Method oop/Base."<init>":(Ljava/lang/String;)V
       5: aload_0
       6: aload_2
       7: putfield      #14                 // Field sex:Ljava/lang/String;
      10: return

  public java.lang.String getSex();
    Code:
       0: aload_0
       1: getfield      #14                 // Field sex:Ljava/lang/String;
       4: areturn

  public void setSex(java.lang.String);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #14                 // Field sex:Ljava/lang/String;
       5: aload_0
       6: invokespecial #29                 // Method oop/Base.getName:()Ljava/lang/String;
       9: pop
      10: return

  public void test(java.lang.String);
    Code:
       0: aload_0
       1: getfield      #14                 // Field sex:Ljava/lang/String;
       4: astore_2
       5: return

  public static void test(oop.Base, java.lang.String, int);
    Code:
       0: getstatic     #36                 // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #42                 // String test BaseExtends
       5: invokevirtual #44                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

5.實(shí)例的構(gòu)造過(guò)程(JVM 指令大體順序):

new someClass //根據(jù)someClass的屬性表開辟內(nèi)存空間馁启,并對(duì)各個(gè)屬性初始化(賦予JVM默認(rèn)值0啊,null啊等等 )返回內(nèi)存空間的對(duì)應(yīng)的“地址”驾孔。對(duì)于基類和擴(kuò)展類有重復(fù)的屬性這種情況(比如都分別聲明了private String name這個(gè)屬性,雖然是不合理不應(yīng)該的設(shè)計(jì)),擴(kuò)展類的實(shí)例在開辟內(nèi)存空間時(shí)惯疙,name會(huì)分別的開辟不同的地址(基類和擴(kuò)展類)翠勉。name對(duì)應(yīng)的兩個(gè)地址是JVM 指令getField或者putField的參數(shù))
invokespecial //調(diào)用自己寫的初始化代碼
retunr aload_0的值;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霉颠,隨后出現(xiàn)的幾起案子对碌,更是在濱河造成了極大的恐慌,老刑警劉巖蒿偎,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朽们,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诉位,警方通過(guò)查閱死者的電腦和手機(jī)骑脱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)苍糠,“玉大人叁丧,你說(shuō)我怎么就攤上這事〈幌ⅲ” “怎么了歹袁?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)寝优。 經(jīng)常有香客問(wèn)我条舔,道長(zhǎng),這世上最難降的妖魔是什么乏矾? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任孟抗,我火速辦了婚禮,結(jié)果婚禮上钻心,老公的妹妹穿的比我還像新娘凄硼。我一直安慰自己,他們只是感情好捷沸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布摊沉。 她就那樣靜靜地躺著,像睡著了一般痒给。 火紅的嫁衣襯著肌膚如雪说墨。 梳的紋絲不亂的頭發(fā)上骏全,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音尼斧,去河邊找鬼姜贡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛棺棵,可吹牛的內(nèi)容都是我干的楼咳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼烛恤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼母怜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起棒动,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤糙申,失蹤者是張志新(化名)和其女友劉穎宾添,沒想到半個(gè)月后船惨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缕陕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年粱锐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛邑。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怜浅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔬崩,到底是詐尸還是另有隱情恶座,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布沥阳,位于F島的核電站跨琳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桐罕。R本人自食惡果不足惜脉让,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望功炮。 院中可真熱鬧溅潜,春花似錦、人聲如沸薪伏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嫁怀。三九已至设捐,卻和暖如春潦牛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挡育。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工巴碗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人即寒。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓橡淆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親母赵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逸爵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)凹嘲,斷路器师倔,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 10,871評(píng)論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法周蹭,內(nèi)部類的語(yǔ)法趋艘,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法凶朗,線程的語(yǔ)...
    子非魚_t_閱讀 31,587評(píng)論 18 399
  • 一瓷胧、創(chuàng)建分支 本地分支 遠(yuǎn)程分支 二、刪除分支 本地分支 遠(yuǎn)程分支 三棚愤、查看分支 本地分支 遠(yuǎn)程分支 四搓萧、切換分支
    魚小念閱讀 382評(píng)論 0 0
  • 櫻花花語(yǔ) 櫻花是愛情與希望的象征,代表著高雅宛畦,質(zhì)樸純潔的愛情瘸洛。櫻花宛如懵懂少女 的,安靜得在春天開放次和,滿樹...
    芠芐whisky閱讀 309評(píng)論 2 6