核心結論先行
| 維度 | static 方法 | 非靜態方法 |
| 調用方式 | 類名.方法名() 或直接 方法名()(同類內) | 必須 new 類名().方法名() 實例化後調用 |
| 所屬對象 | 類級別,加載時就存在 | 實例級別,屬於具體對象 |
| 訪問權限 | 只能直接訪問 static 成員 | 可訪問所有成員(static + 非 static) |
| this/super | 不可用 | 可用 this 代表當前調用對象 |
代碼實戰演示
package lsg.ap.april4th2;
class Person {
private String name = "劉德華";
private int age = 45;
static String country = "中國"; // 靜態共享屬性
public String getName() { return name; }
public void setName(String name) { this.name = name; } // this 解決變量遮蔽
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
public class PersonClass {
public void show() { System.out.println("哈哈"); } // 非靜態
public static void show2() { System.out.println("哈哈你妹"); } // 靜態
public static void main(String[] args) {
Person s1 = new Person();
Person s2 = new Person();
PersonClass s3 = new PersonClass();
s3.show(); // 必須實例化調用
show2(); // 同類內靜態方法直接調用,類名可省略
s1.setName("林青霞");
s1.setAge(27);
s1.country = "美國"; // 警告:靜態成員建議類名訪問
s2.country = "日本"; // 共享屬性,最終值為「日本」
System.out.println(s1.getName() + "---" + s1.getAge());
System.out.println(s2.getName() + "---" + s2.getAge());
System.out.println(Person.country); // 推薦:類名訪問靜態字段
}
}
關鍵知識點深度解析
1. static 共享語義
static String country 屬於 Person 類,所有實例共享同一內存地址。
s1.country = "美國" 後 s2.country 讀取即為「美國」;再執行 s2.country = "日本",s1.country 也變為「日本」。
- 編譯器會對實例訪問靜態字段發出警告,規範寫法:
Person.country。
2. this 關鍵字三大作用
- 區分同名變量:
this.name = name 區分成員變量與參數。
- 構造器鏈調用:
this(...) 必須首行調用另一構造器。
- 返回當前對象:
return this 支持鏈式調用。
核心規則:this 代表調用該方法的具體對象,誰調用,this 就指向誰。
3. 靜態 vs 非靜態調用規則口訣
靜態調靜態:直接調,類名可省;
靜態調非靜:不可為,須實例;
非靜調靜態:直接調,類名可省;
非靜調非靜:直接調,this 隱含。
4. static vs final 區別
| 關鍵字 | 語義 | 類比 C | 值可變性 |
| static | 類級共享、生命周期隨類 | extern 全局變量 | 可修改 |
| final | 不可變引用/值、常量 | #define 常量 | 初始化後不可變 |
常見錯誤與最佳實踐
- ❌
static 方法中使用 this → 編譯錯誤。
- ❌
static 方法直接調用非靜態方法/字段 → 編譯錯誤。
- ✅ 工具類方法定義為
static(如 Math.max、Collections.sort)。
- ✅ 狀態相關操作定義為非靜態(如
setName、getAge)。
- ✅ 靜態常量
static final 大寫下劃線命名(DEFAULT_CAPACITY)。