首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java this 與 super 關鍵字全解析:引用機制、構造器鏈與遮蔽問題

     編輯:Java 相關知識

this:當前對象引用

this 代表正在執行方法/構造器的對象實例,非靜態上下文專用。

四大核心用法

1. 消除字段遮蔽(最常用)

public class Person {
    private String name;  // 實例字段
    
    public Person(String name) {  // 參數遮蔽字段
        this.name = name;         // this.字段 = 參數
    }
    
    public void setName(String name) {
        this.name = name;         // 同理
    }
}

規則:作用域最近者優先。無遮蔽時 this 可省略,但規範代碼建議保留 增強可讀性。

2. 構造器鏈調用(減少重複代碼)

public class Book {
    private String title;
    private String author;
    private int pages;
    
    // 全參構造器:核心初始化邏輯
    public Book(String title, String author, int pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
    }
    
    // 便利構造器:委託全參構造器
    public Book(String title, String author) {
        this(title, author, 0);  // 必須為構造器第一條語句
    }
    
    public Book(String title) {
        this(title, "Unknown");
    }
}
  • this(...) 必須放在構造器第一行,一個構造器最多一條。
  • 不能與 super(...) 共存。
  • 形成委託鏈,最終到達全參構造器,保證初始化邏輯單一入口。

3. 返回當前對象(鏈式調用/建造者模式)

public class StringBuilder {
    private char[] buffer;
    
    public StringBuilder append(String s) {
        // 追加邏輯...
        return this;  // 返回自身,支持鏈式
    }
}

// 使用
new StringBuilder().append("A").append("B").append("C");

4. 傳遞當前對象(回調/事件註冊)

public class EventSource {
    public void register(Listener l) { ... }
}

public class MyComponent implements Listener {
    public void init(EventSource source) {
        source.register(this);  // 傳遞自身作為監聽器
    }
}

super:父類對象引用

super 代表當前對象的父類部分,非靜態上下文專用。

三大核心用法

1. 調用父類構造器(子類構造義務)

public class Animal {
    protected String species;
    public Animal(String species) { this.species = species; }
}

public class Dog extends Animal {
    private String name;
    
    public Dog(String name) {
        super("Canine");  // 顯式調用父類帶參構造器
        this.name = name;
    }
    
    public Dog(String name, String species) {
        super(species);   // 透傳參數
        this.name = name;
    }
}
  • 子類構造器首行隱式 super()(調用父類無參構造器)。
  • 父類無無參構造器 → 子類必須顯式 super(args)。
  • 必須為構造器第一條語句,不可與 this(...) 共存。

2. 調用被覆寫的父類方法

public class Base {
    public void greet() { System.out.println("Hello from Base"); }
}

public class Derived extends Base {
    @Override public void greet() {
        super.greet();  // 調用父類版本
        System.out.println("Hello from Derived");
    }
    
    public void callBoth() {
        greet();      // 調用覆寫版(多態)
        super.greet(); // 顯式調用父類版
    }
}

未覆寫時 super.method() 可省略(直接 method() 即調用父類)。

3. 訪問被遮蔽的父類字段(極少用,不推薦)

public class Base { protected int value = 1; }
public class Derived extends Base { private int value = 2; }

public class Test {
    public static void main(String[] args) {
        Derived d = new Derived();
        System.out.println(d.value);        // 2 (子類字段)
        System.out.println(((Base)d).value); // 1 (父類字段,需強轉)
        // 或在 Derived 內部:
        // System.out.println(super.value);  // 1
    }
}

最佳實踐:避免字段遮蔽,字段命名區分層級或用 private 封裝 + getter/setter。

關鍵限制:非靜態上下文專用

public class Example {
    public static void staticMethod() {
        // this.toString();  // 編譯錯誤:靜態方法無 this
        // super.toString(); // 編譯錯誤:靜態方法無 super
    }
    
    public void instanceMethod() {
        this.toString();   // ✓
        super.toString();  // ✓
    }
}

原因:靜態方法屬於類,不屬於具體實例,無 this/super 綁定對象。

綜合實戰:構造器鏈 + 字段遮蔽 + 方法覆寫

public class Vehicle {
    protected String brand;
    protected int speed;
    
    public Vehicle(String brand) {
        this.brand = brand;
        this.speed = 0;
    }
    
    public void accelerate(int increment) {
        speed += increment;
    }
}

public class Car extends Vehicle {
    private int gear;  // 子類特有字段
    
    // 構造器鏈
    public Car(String brand) {
        this(brand, 1);  // 委託全參
    }
    
    public Car(String brand, int gear) {
        super(brand);    // 父類初始化
        this.gear = gear;
    }
    
    // 覆寫並擴展
    @Override
    public void accelerate(int increment) {
        super.accelerate(increment);  // 父類邏輯
        if (speed > 60 && gear < 3) shiftGear(3); // 子類擴展
    }
    
    private void shiftGear(int g) { gear = g; }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved