最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中super與this用法及底層原理解析

 更新時(shí)間:2025年11月01日 09:41:41   作者:故淵ZY  
在 Java 面向?qū)ο缶幊讨?this和super絕非簡單的語法糖,它們是連接對(duì)象實(shí)例與類繼承體系的核心橋梁,本文將從底層原理、復(fù)雜場景和反編譯視角,重新解讀this與super的本質(zhì),感興趣的朋友跟隨小編一起看看吧

理解 super 和 this 關(guān)鍵字的基本概念

在 Java 面向?qū)ο缶幊讨校?code>this和super絕非簡單的語法糖,它們是連接對(duì)象實(shí)例與類繼承體系的核心橋梁。深入理解這兩個(gè)關(guān)鍵字,不僅能解決日常開發(fā)中的變量沖突、繼承復(fù)用問題,更能幫助我們看透 Java 對(duì)象的內(nèi)存布局與初始化邏輯。本文將從底層原理、復(fù)雜場景和反編譯視角,重新解讀thissuper的本質(zhì)。

this 關(guān)鍵字:對(duì)象自我引用的底層邏輯

this的本質(zhì)是當(dāng)前對(duì)象的內(nèi)存引用,在實(shí)例方法被調(diào)用時(shí)由 JVM 自動(dòng)傳遞。從字節(jié)碼層面看,所有實(shí)例方法的第一個(gè)參數(shù)都是this(只是編譯器隱式處理),這也是this能直接訪問當(dāng)前對(duì)象成員的底層原因。

當(dāng)成員變量與局部變量同名時(shí),this的作用是明確指定訪問對(duì)象堆內(nèi)存中的成員變量,而非棧內(nèi)存中的局部變量

public class User {
    private String name; // 堆內(nèi)存中(對(duì)象成員)
    public void setName(String name) { // 棧內(nèi)存中(局部變量)
        this.name = name; // 明確將棧中name的值賦值給堆中name
    }
}

反編譯字節(jié)碼顯示:

  • aload_0 加載 this 引用
  • aload_1 加載局部變量 name
  • putfield 將局部變量值賦給堆內(nèi)存中的成員變量

構(gòu)造方法調(diào)用鏈:this (...) 的初始化邏輯

this(...)在構(gòu)造方法中調(diào)用其他構(gòu)造方法,本質(zhì)是復(fù)用初始化邏輯,避免代碼冗余。但需注意:JVM 在執(zhí)行構(gòu)造方法時(shí),會(huì)先完成所有this(...)調(diào)用,最終執(zhí)行最底層的構(gòu)造方法,再逐層返回

public class Order {
    public Order(String id, String product, int count, double price) {
        this.id = id;
        System.out.println("全參構(gòu)造初始化");
    }
    public Order(String id, String product, int count) {
        this(id, product, count, 0.0);
        System.out.println("省略price的構(gòu)造");
    }
    public Order(String id) {
        this(id, "未知商品", 1);
        System.out.println("僅id的構(gòu)造");
    }
}

輸出順序:

  • 全參構(gòu)造初始化
  • 省略price的構(gòu)造
  • 僅id的構(gòu)造

鏈?zhǔn)秸{(diào)用與 Builder 模式:this 作為返回值

this作為方法返回值時(shí),實(shí)際返回的是當(dāng)前對(duì)象的引用,這使得連續(xù)調(diào)用同一對(duì)象的方法成為可能,是 Builder 模式的核心實(shí)現(xiàn)手段。

public class UserBuilder {
    public UserBuilder setName(String name) {
        this.name = name;
        return this;
    }
    public User build() {
        return new User(name, age, email);
    }
}

優(yōu)勢:相比傳統(tǒng)的 setter 方法,鏈?zhǔn)秸{(diào)用使對(duì)象構(gòu)建邏輯更清晰,且能在編譯期避免 “未完成初始化” 的問題。

內(nèi)部類中的 this:區(qū)分內(nèi)外層實(shí)例

在非靜態(tài)內(nèi)部類中,this默認(rèn)指向內(nèi)部類實(shí)例;若需訪問外部類實(shí)例,需用外部類名.this。這是因?yàn)?strong>非靜態(tài)內(nèi)部類會(huì)隱式持有外部類的引用

public class Outer {
    public class Inner {
        public void show() {
            System.out.println(this.innerField); // 內(nèi)部類字段
            System.out.println(Outer.this.outerField); // 外部類字段
        }
    }
}
 

內(nèi)存隱患:非靜態(tài)內(nèi)部類持有外部類引用可能導(dǎo)致內(nèi)存泄漏(如 Activity 中的內(nèi)部類未及時(shí)釋放)。此時(shí)可改用靜態(tài)內(nèi)部類,并通過弱引用持有外部類

super 關(guān)鍵字:繼承體系中的父類引用

super的本質(zhì)是當(dāng)前對(duì)象中父類部分的引用。在 JVM 中,子類對(duì)象的內(nèi)存布局會(huì)包含父類的所有成員(私有成員不可直接訪問,但存在于內(nèi)存中),super就是訪問這部分內(nèi)存的入口

訪問父類成員:突破子類的 “覆蓋” 屏蔽

當(dāng)子類與父類存在同名成員(變量或方法)時(shí),子類的成員會(huì) “屏蔽” 父類的成員,而super能繞過屏蔽,直接訪問父類版

class Parent {
    String name = "Parent";
    public void print() {
        System.out.println("Parent print");
    }
}
class Child extends Parent {
    String name = "Child";
    @Override
    public void print() {
        System.out.println("Child print");
    }
    public void show() {
        System.out.println(name); // Child
        System.out.println(super.name); // Parent
        print(); // Child print
        super.print(); // Parent print
    }
}

構(gòu)造方法中的 super(...):父類初始化的強(qiáng)制要求

子類構(gòu)造方法必須先調(diào)用父類構(gòu)造方法,父類成員需先初始化。

多層繼承下,super(...) 逐層向上調(diào)用直到 Object 類的無參構(gòu)造。

class Grandparent {
    public Grandparent() {
        System.out.println("Grandparent");
    }
}
class Parent extends Grandparent {
    public Parent() {
        System.out.println("Parent");
    }
}
class Child extends Parent {
    public Child() {
        System.out.println("Child");
    }
}

輸出順序:

  • Grandparent
  • Parent
  • Child

動(dòng)態(tài)綁定中的 super:繞過子類重寫的 “后門”

在多態(tài)場景下,子類對(duì)象向上轉(zhuǎn)型為父類引用時(shí),調(diào)用的方法是子類重寫后的版本(動(dòng)態(tài)綁定)。而super.方法()能強(qiáng)制調(diào)用父類的原始方法,不受動(dòng)態(tài)綁定影響。

class Animal {
    public void eat() {
        System.out.println("動(dòng)物進(jìn)食");
    }
}
class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨頭");
    }
    public void parentEat() {
        super.eat(); // 直接調(diào)用父類的eat
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog(); // 向上轉(zhuǎn)型
        animal.eat(); // 動(dòng)態(tài)綁定:調(diào)用Dog的eat(輸出“狗吃骨頭”)
        Dog dog = new Dog();
        dog.parentEat(); // 調(diào)用Animal的eat(輸出“動(dòng)物進(jìn)食”)
    }
}

字節(jié)碼差異

普通方法調(diào)用(如animal.eat())使用invokevirtual指令,觸發(fā)動(dòng)態(tài)綁定;super.eat()使用invokespecial指令,直接調(diào)用父類方法,不經(jīng)過動(dòng)態(tài)綁定。

this 與 super 的深層對(duì)比:從內(nèi)存到執(zhí)行機(jī)制

維度this 關(guān)鍵字super 關(guān)鍵字
本質(zhì)引用指向當(dāng)前對(duì)象的完整內(nèi)存地址指向當(dāng)前對(duì)象中父類成員的內(nèi)存區(qū)域
編譯期處理轉(zhuǎn)換為aload_0指令(加載當(dāng)前對(duì)象引用)轉(zhuǎn)換為invokespecial指令(調(diào)用父類成員)
訪問權(quán)限可訪問當(dāng)前類的所有成員(包括繼承的)只能訪問父類的非私有成員(private 不可見)
在構(gòu)造方法中的作用調(diào)用當(dāng)前類其他構(gòu)造,形成初始化鏈調(diào)用父類構(gòu)造,確保父類成員先初始化
與多態(tài)的關(guān)系指向?qū)嶋H對(duì)象(多態(tài)下仍為子類實(shí)例)繞過多態(tài),直接訪問父類版本

關(guān)鍵原理:對(duì)象的內(nèi)存布局與 super 的定位

當(dāng)創(chuàng)建子類對(duì)象時(shí),JVM 會(huì)在堆內(nèi)存中分配一塊連續(xù)空間,包含:

  • 父類的所有成員變量(按繼承層次排列);
  • 子類的成員變量;
  • 對(duì)象頭(包含類型指針等信息)。

super的作用就是定位到這塊內(nèi)存中 “父類成員” 的起始位置,而this則指向整個(gè)對(duì)象的起始位置。

子類對(duì)象內(nèi)存布局:
[父類成員變量區(qū)][子類成員變量區(qū)][對(duì)象頭]
    ↑               ↑
  super指向        this指向(整個(gè)對(duì)象起始)

避坑指南:this 與 super 的常見錯(cuò)誤場景

靜態(tài)方法中使用 this/super:編譯報(bào)錯(cuò)的底層原因 靜態(tài)方法屬于類,而非實(shí)例,其字節(jié)碼中沒有this參數(shù)。因此在靜態(tài)方法中使用thissuper,編譯器會(huì)直接報(bào)錯(cuò)。

public class Test {
    public static void method() {
        // this.name; // 編譯錯(cuò)誤:static方法無this
        // super.method(); // 編譯錯(cuò)誤:static方法無super
    }
}

構(gòu)造方法中調(diào)用被子類重寫的方法:隱藏的邏輯陷阱 若父類構(gòu)造方法中調(diào)用了一個(gè)被子類重寫的方法,會(huì)導(dǎo)致子類對(duì)象未完成初始化時(shí)就執(zhí)行子類方法,可能引發(fā)空指針異常。

class Parent {
    public Parent() {
        init(); 
    }
    public void init() {
        System.out.println("Parent init");
    }
}
class Child extends Parent {
    private String name;
    @Override
    public void init() {
        System.out.println(name.length()); 
    }
    public static void main(String[] args) {
        new Child(); 
    }
}

解決方案:父類構(gòu)造中避免調(diào)用可被重寫的方法(可將方法聲明為privatefinal)。

this (...) 與 super (...) 共存:構(gòu)造方法的語法禁區(qū) this(...)super(...)都必須放在構(gòu)造方法的第一行,因此二者不能同時(shí)出現(xiàn)。

public class Test {
    public Test() {
        // this(1); 與super()不能同時(shí)存在
        super(); 
    }
    public Test(int a) {}
}

實(shí)戰(zhàn)進(jìn)階:this 與 super 在設(shè)計(jì)模式中的應(yīng)用

模板方法模式:super 調(diào)用父類骨架邏輯 模板方法模式中,父類定義算法骨架,子類重寫具體步驟。通過super調(diào)用父類模板方法,確保算法結(jié)構(gòu)不變。

abstract class AbstractProcessor {
    public final void process() {
        step1();
        step2(); 
        step3();
    }
    protected void step1() {
        System.out.println("固定步驟1");
    }
    protected abstract void step2(); 
    protected void step3() {
        System.out.println("固定步驟3");
    }
}
class ConcreteProcessor extends AbstractProcessor {
    @Override
    protected void step2() {
        System.out.println("子類實(shí)現(xiàn)的步驟2");
    }
    public static void main(String[] args) {
        AbstractProcessor processor = new ConcreteProcessor();
        processor.process(); 
    }
}

裝飾器模式:this 傳遞當(dāng)前裝飾對(duì)象 裝飾器模式中,裝飾類通過this將自身傳遞給被裝飾對(duì)象,實(shí)現(xiàn)功能增強(qiáng)的鏈?zhǔn)蒋B加。

interface Component {
    void operation();
}
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("基礎(chǔ)功能");
    }
}
abstract class Decorator implements Component {
    protected Component component;
    public Decorator(Component component) {
        this.component = component;
    }
}
class LogDecorator extends Decorator {
    public LogDecorator(Component component) {
        super(component);
    }
    @Override
    public void operation() {
        System.out.println("日志開始");
        component.operation(); 
        System.out.println("日志結(jié)束");
    }
}
class TimeDecorator extends Decorator {
    public TimeDecorator(Component component) {
        super(component);
    }
    @Override
    public void operation() {
        long start = System.currentTimeMillis();
        component.operation();
        System.out.println("耗時(shí):" + (System.currentTimeMillis() - start));
    }
}
public class Test {
    public static void main(String[] args) {
        Component component = new TimeDecorator(
            new LogDecorator(new ConcreteComponent())
        );
        component.operation(); 
    }
}

總結(jié)

thissuper是 Java 面向?qū)ο蟮?“隱形支柱”:

  • this是對(duì)象的 “自我認(rèn)知”,讓實(shí)例能清晰訪問自身成員、復(fù)用構(gòu)造邏輯,并支撐鏈?zhǔn)秸{(diào)用等優(yōu)雅設(shè)計(jì);
  • super是子類對(duì)父類的 “繼承契約”,確保父類初始化優(yōu)先,同時(shí)提供訪問父類成員的安全通道,是繼承與多態(tài)的基礎(chǔ)。

深入理解二者的關(guān)鍵,在于看透其背后的內(nèi)存模型與執(zhí)行機(jī)制 ——this指向?qū)ο笳w,super指向?qū)ο笾械母割惒糠郑吖餐瑯?gòu)成了 Java 對(duì)象的完整邏輯。

到此這篇關(guān)于Java中super與this的深入解析的文章就介紹到這了,更多相關(guān)java super與this內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

樟树市| 永年县| 车致| 禹州市| 九江县| 太原市| 南华县| 萍乡市| 哈巴河县| 宁夏| 玛沁县| 泊头市| 龙海市| 信宜市| 垣曲县| 新安县| 凯里市| 鸡泽县| 成安县| 通榆县| 塔河县| 凌源市| 抚顺县| 阿巴嘎旗| 信阳市| 黄石市| 个旧市| 湾仔区| 桓仁| 凯里市| 嘉禾县| 马鞍山市| 绩溪县| 沁水县| 拜城县| 房产| 尼玛县| 大悟县| 长海县| 渝北区| 同江市|