方法是 Java 程序中最小的功能單元,封裝特定業務邏輯,支持參數化輸入與結果輸出。掌握方法定義語法、四類方法分類、重載機制、參數傳遞本質(值傳遞)、返回值處理,是編寫清晰、可維護、可測試代碼的前提。
| 要素 | 說明 | 示例 |
| 訪問修飾符 | 權限控制 | public、protected、private、默認 |
| 返回值類型 | 無返回寫 void;有返回寫具體類型 | int、String、User、void |
| 方法名 | 標識符,駝峰命名,動詞開頭 | calculateSum、getUserById |
| 參數列表 | 0~N 個「類型 變量名」,逗號分隔 | (int a, String name) |
二、四類方法分類與實戰
1. 無參無返回值
public void welcome() {
System.out.println("Welcome to Java!");
}
// 調用
obj.welcome(); // 直接調用,無接收
2. 無參有返回值
public int getRandomNumber() {
return (int)(Math.random() * 100); // 必須 return 兼容類型值
}
// 調用
int num = obj.getRandomNumber(); // 接收返回值
3. 有參無返回值
public void greet(String name) {
System.out.println("Hello, " + name + "!");
}
// 調用
obj.greet("Alice"); // 實參傳遞,無接收
4. 有參有返回值
public String buildMessage(String name, int age) {
return "User: " + name + ", Age: " + age;
}
// 調用
String msg = obj.buildMessage("Bob", 25);
三、參數傳遞機制:值傳遞鐵律
核心結論
**Java 只有值傳遞**。
- 基本類型:直接複製值,方法內修改**不影響**原變量。
- 引用類型:複製**引用地址**(指針值),方法內可通過引用**修改對象內容**,但**不能改變原引用指向新對象**。
實戰驗證
public class ParamTest {
// 基本類型:不影響原值
public void changePrimitive(int x) {
x = 20;
}
// 引用類型:可修改對象內容
public void changeObject(StringBuilder sb) {
sb.append(" World"); // 修改內容 ✓
}
// 引用類型:無法改變原引用指向
public void changeRef(StringBuilder sb) {
sb = new StringBuilder("New"); // 僅改變局部參數指向 ✗
}
public static void main(String[] args) {
ParamTest t = new ParamTest();
int a = 10;
t.changePrimitive(a);
System.out.println(a); // 10
StringBuilder s1 = new StringBuilder("Hello");
t.changeObject(s1);
System.out.println(s1); // Hello World
StringBuilder s2 = new StringBuilder("Hello");
t.changeRef(s2);
System.out.println(s2); // Hello (未變)
}
}
交換兩個變量值為什麼失效?
// 錯誤嘗試
public void swap(int a, int b) {
int temp = a; a = b; b = temp; // 僅交換局部副本
}
// 正確方案:封裝為對象 / 返回數組 / 使用集合 / 原子類
public int[] swap(int a, int b) {
return new int[]{b, a};
}
四、返回值處理規範
- void 方法:不能有
return 值;,可單獨 return; 提前結束。
- 非 void 方法:所有路徑必須有
return 兼容類型值;(編譯器強制檢查)。
- 返回值類型兼容:子類型可返回給父類型變量(多態)、基本類型自動提升(int→double)。
- 最多一個返回值:需多值時用對象/數組/集合/Map 封裝。
五、方法重載
定義
同一類中,**方法名相同**,**參數列表不同**(個數、類型、順序),與修飾符、返回類型無關。
重載示例
public class Calculator {
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
public int add(int a, int b, int c) { return a + b + c; }
public String add(String a, String b) { return a + b; } // 參數類型不同
}
調用匹配規則
- 精確匹配參數類型。
- 基本類型自動提升:
byte→short→int→long→float→double、char→int。
- 自動拆箱/裝箱:
Integer→int、int→Integer。
- 可變參數
(T... args) 優先級**最低**(兜底匹配)。
- 歧義報錯:
add(1,2) 滿足 int,int 和 double,double → 編譯錯誤「引用模糊」。
重載 vs 重寫 對比
| 維度 | Overload (重載) | Override (重寫) |
| 位置 | 同一類 | 子父類 |
| 方法名 | 相同 | 相同 |
| 參數列表 | **必須不同** | **必須相同** |
| 返回類型 | 可異 | 協變(子類型) |
| 拋出異常 | 無關 | 子集 |
| 訪問權限 | 無關 | 不小於父類 |
| 綁定時機 | 編譯期(靜態) | 運行期(動態) |
| 多態性 | 無 | 體現多態 |
六、可變參數
public void printAll(String... names) { // 本質是 String[] names
for (String n : names) System.out.println(n);
}
// 調用
printAll("A", "B", "C");
printAll(new String[]{"X", "Y"}); // 也可傳數組
printAll(); // 可傳 0 參
- 一個方法**最多一個**可變參數,且必須在**參數列表最後**。
- 內部當數組處理,
names.length、names[0] 均可用。
- 重載優先級:固定參數 > 可變參數。
七、遞歸調用
public long factorial(int n) {
if (n <= 1) return 1; // 基線條件
return n * factorial(n - 1); // 遞歸步驟
}
- 必須有**基線條件**終止遞歸,否則
StackOverflowError。
- 每次調用創建新棧幀,深度受限於棧大小(通常幾千層)。
- 尾遞歸優化:Java **不支持**(JVM 無 TCO),深度遞歸改用迭代或顯式棧。
八、最佳實踐清單
- 單一職責:一個方法只做一件事,行數控制在 20-30 行以內。
- 命名規範:動詞開頭(get/set/is/calculate/process/validate),見名知意。
- 參數驗證:公共方法首行檢查非空、範圍、狀態,拋
IllegalArgumentException。
- 避免長參數列表:>3 參數考慮引入參數對象/Builder/Map。
- 優先返回值,輸出參數慎用:Java 無引用傳遞,輸出參數需包裝類/數組/集合,可讀性差。
- 異常處理:業務異常拋出 checked/unchecked 異常,勿吞沒;資源用 try-with-resources。
- 靜態方法慎用:無狀態工具類適合;有狀態/需多態/需測試時用實例方法。
- 文檔註釋:公共 API 必寫 Javadoc(@param @return @throws @see)。
總結
方法是 Java 面向過程與面向對象的橋樑。深入理解「值傳遞本質、重載匹配規則、返回值約束、遞歸棧機制」,配合「單一職責、參數驗證、異常處理、文檔規範」工程實踐,能構建出高內聚、低耦合、易測試、易維護的方法體系,為類設計、模塊劃分、架構演進奠定堅實基礎。
- 上一篇文章: Java 面試核心題庫精選:基礎語法、集合、並發、JVM、Web 全覆蓋
- 下一篇文章: Java 進階:LinkedList 源碼深度解析(基於 JDK 1.7)
Copyright ©
程式碼之家 All Rights Reserved