11個(gè)值得借鑒的Java?return寫(xiě)法分享
前言
return 這個(gè)關(guān)鍵字,相信大家每天都在用。
它就像一把錘子,敲打著我們代碼里的每一個(gè)出口。
但捫心自問(wèn),我們真的把這把錘子用好了嗎?
今天,不想聊什么高深莫測(cè)的設(shè)計(jì)模式,也不敢妄稱(chēng)“最佳實(shí)踐”。
只想結(jié)合自己這些年在項(xiàng)目摸爬滾打中踩過(guò)的一些坑、積累的一點(diǎn)心得,和大家分享一些關(guān)于 return 的、或許能讓我們的代碼更規(guī)范、更優(yōu)雅、更易讀的寫(xiě)法。
權(quán)當(dāng)拋磚引玉,希望能引發(fā)大家的一些思考。
耐心看完,你一定有所收獲。
1. 提前返回(衛(wèi)語(yǔ)句):讓主邏輯更清晰
這是最常見(jiàn)也是非常推薦的一種模式。
核心思想是:在方法開(kāi)頭處理掉所有“異常”或“特殊”情況,讓方法的主體部分專(zhuān)注于核心邏輯。
反面教材 :
public void processData(Data data) {
if (data != null) {
if (data.isValid()) {
if (checkPermission(data)) {
// 核心邏輯開(kāi)始...
System.out.println("處理數(shù)據(jù):" + data.getContent());
// ...
// 大量核心代碼嵌套在這里
// ...
System.out.println("處理完成");
} else {
System.out.println("權(quán)限不足");
}
} else {
System.out.println("數(shù)據(jù)無(wú)效");
}
} else {
System.out.println("數(shù)據(jù)為null");
}
}
很難評(píng),嵌套過(guò)深,核心邏輯被包裹在層層 if-else 中,可讀性太差。
推薦寫(xiě)法 :
public void processData(Data data) {
if (data == null) {
System.out.println("數(shù)據(jù)為null");
return; // 提前返回
}
if (!data.isValid()) {
System.out.println("數(shù)據(jù)無(wú)效");
return; // 提前返回
}
if (!checkPermission(data)) {
System.out.println("權(quán)限不足");
return; // 提前返回
}
// --- 核心邏輯開(kāi)始 ---
// 經(jīng)過(guò)前面的衛(wèi)語(yǔ)句檢查,這里的data一定是有效且有權(quán)限的
System.out.println("處理數(shù)據(jù):" + data.getContent());
// ...
// 核心代碼不再嵌套,非常清晰
// ...
System.out.println("處理完成");
}
通過(guò)提前 return,避免了深層嵌套,讓主要的處理流程更加順暢,代碼邏輯一目了然。
配得上“優(yōu)雅”二字。
2. 避免 return 后的 else 塊
當(dāng) if 分支中包含 return 語(yǔ)句時(shí),其后的代碼天然就是 else 的邏輯,無(wú)需顯式寫(xiě)出 else。
反面教材 :
public String getStatus(int code) {
if (code == 0) {
return "Success";
} else {
// 其他邏輯
return "Error: " + getErrorMessage(code);
}
}
雖然沒(méi)錯(cuò),但 else 顯得有些多余,未免畫(huà)蛇添足。
推薦寫(xiě)法 :
public String getStatus(int code) {
if (code == 0) {
return "Success";
}
// 如果 code == 0,上面的 return 已經(jīng)退出方法了
// 能執(zhí)行到這里,說(shuō)明 code != 0,天然就是 else 的邏輯
return "Error: " + getErrorMessage(code);
}
代碼更簡(jiǎn)潔,減少了一層不必要的縮進(jìn)。
3. 簡(jiǎn)化布爾返回
直接返回布爾表達(dá)式的結(jié)果,而不是使用 if-else 返回 true 或 false。
反面教材 :
public boolean isEligible(User user) {
if (user.getAge() >= 18 && user.isActive()) {
return true;
} else {
return false;
}
}
點(diǎn)評(píng):非常啰嗦。
推薦寫(xiě)法 :
public boolean isEligible(User user) {
return user.getAge() >= 18 && user.isActive();
}
一行搞定,清晰明了。
4. 減少不必要的臨時(shí)變量
如果一個(gè)變量?jī)H僅是為了存儲(chǔ)即將 return 的值,可以考慮直接 return 表達(dá)式的結(jié)果。
反面教材:
public int calculateSum(int a, int b) {
int sum = a + b;
return sum;
}
public String getUserGreeting(User user) {
String greeting = "Hello, " + user.getName();
return greeting;
}
sum 和 greeting 變量并非必需。
推薦寫(xiě)法 :
public int calculateSum(int a, int b) {
return a + b;
}
public String getUserGreeting(User user) {
// 如果 user.getName() 調(diào)用成本高或需要復(fù)用,臨時(shí)變量可能有意義
// 但在這個(gè)簡(jiǎn)單場(chǎng)景下,直接返回更簡(jiǎn)潔
return "Hello, " + user.getName();
}
更直接。
但注意,如果表達(dá)式復(fù)雜或計(jì)算結(jié)果需要復(fù)用,還是考慮使用臨時(shí)變量,可以提高可讀性或效率,需要權(quán)衡。
5. 巧用三元運(yùn)算符
對(duì)于簡(jiǎn)單的二選一返回邏輯,三元運(yùn)算符 ?: 是 if-else 的簡(jiǎn)潔替代。
反面教材 :
public String getLevel(int score) {
String level;
if (score >= 60) {
level = "Pass";
} else {
level = "Fail";
}
return level;
}
推薦寫(xiě)法 :
public String getLevel(int score) {
return score >= 60 ? "Pass" : "Fail";
}
一行代碼,清晰表達(dá)了條件選擇。
但是千萬(wàn)注意不要濫用,過(guò)分嵌套的三元運(yùn)算符會(huì)降低可讀性。
6. 返回空集合而非 null
方法約定返回集合類(lèi)型(List, Set, Map等)時(shí),如果沒(méi)有數(shù)據(jù),應(yīng)返回空集合而不是 null。
這可以避免調(diào)用方不必要的 null 檢查。
反面教材 :
public List<String> getUsers(String department) {
List<String> users = findUsersByDepartment(department);
if (users.isEmpty()) { // 或者 users == null
return null; // 調(diào)用方需要檢查 null !
}
return users;
}
推薦寫(xiě)法 :
import java.util.Collections;
import java.util.List;
public List<String> getUsers(String department) {
List<String> users = findUsersByDepartment(department);
// 假設(shè) findUsersByDepartment 可能返回 null 或空 List
if (users == null || users.isEmpty()) {
return Collections.emptyList(); // 返回不可變的空列表
}
// 或者更好的是,確保 findUsersByDepartment 內(nèi)部就返回空列表而不是 null
return users;
}
// 調(diào)用方代碼,無(wú)需擔(dān)心 NullPointerException
List<String> userList = service.getUsers("IT");
for (String user : userList) { // 直接遍歷,安全
System.out.println(user);
}調(diào)用方代碼更健壯、簡(jiǎn)潔,符合“防御性編程”的原則。
7. 利用 Optional 優(yōu)雅處理可能缺失的值
當(dāng)方法可能返回一個(gè)值,也可能什么都不返回時(shí),使用 Optional<T> 作為返回類(lèi)型比返回 null 更能明確表達(dá)這種可能性,并引導(dǎo)調(diào)用方正確處理。
反面教材 :
public User findUserById(String id) {
// ... 查詢(xún)邏輯 ...
if (found) {
return user;
} else {
return null; // 調(diào)用方必須檢查 null
}
}
// 調(diào)用方
User user = findUserById("123");
if (user != null) { // 繁瑣的 null 檢查
System.out.println(user.getName());
}
推薦寫(xiě)法 :
import java.util.Optional;
public Optional<User> findUserById(String id) {
// ... 查詢(xún)邏輯 ...
if (found) {
return Optional.of(user);
} else {
return Optional.empty();
}
}
// 調(diào)用方
findUserById("123")
.ifPresent(user -> System.out.println(user.getName())); // 清晰地處理存在的情況
// 或者提供默認(rèn)值
String userName = findUserById("123")
.map(User::getName)
.orElse("Unknown User");
Optional 強(qiáng)制調(diào)用者思考值不存在的情況,并通過(guò)鏈?zhǔn)秸{(diào)用提供了更流暢的處理方式,減少空指針風(fēng)險(xiǎn)。
但是Java的Optional非常頭疼,如果使用時(shí)不加注意,本應(yīng)返回Optional的方法,返回了null,反而會(huì)增加負(fù)擔(dān),因此團(tuán)隊(duì)的開(kāi)發(fā)規(guī)范至關(guān)重要。
8. 循環(huán)中的提前返回
在循環(huán)中查找元素或滿(mǎn)足某個(gè)條件時(shí),一旦找到或滿(mǎn)足,應(yīng)立即 return,避免不必要的后續(xù)迭代。
反面教材 :
public Product findProductByName(List<Product> products, String name) {
Product foundProduct = null;
for (Product product : products) {
if (product.getName().equals(name)) {
foundProduct = product;
break; // 找到后跳出循環(huán)
}
}
// 循環(huán)結(jié)束后再返回
return foundProduct;
}
需要一個(gè)額外的 foundProduct 變量,并且在循環(huán)外返回。
浪費(fèi)性能。
推薦寫(xiě)法 :
public Product findProductByName(List<Product> products, String name) {
for (Product product : products) {
if (product.getName().equals(name)) {
return product; // 一旦找到,立即返回
}
}
// 循環(huán)正常結(jié)束,說(shuō)明沒(méi)找到
return null; // 或者 Optional.empty()
}
邏輯更直接,代碼更緊湊。
9. 利用 switch 表達(dá)式(Java 14+)
現(xiàn)在Java的 switch 表達(dá)式可以直接返回值,使得基于多分支選擇的返回更加簡(jiǎn)潔。
反面教材 (傳統(tǒng) switch 語(yǔ)句):
public String getWeekdayType(DayOfWeek day) {
String type;
switch (day) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
type = "Workday";
break;
case SATURDAY:
case SUNDAY:
type = "Weekend";
break;
default:
throw new IllegalArgumentException("Invalid day: " + day);
}
return type;
}
推薦寫(xiě)法 (使用 switch 表達(dá)式):
public String getWeekdayType(DayOfWeek day) {
return switch (day) {
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Workday";
case SATURDAY, SUNDAY -> "Weekend";
// default 分支通常是必需的,除非覆蓋了所有枚舉常量
// 如果邏輯確定上面的 case 已經(jīng)覆蓋所有情況,可以不寫(xiě) default,
// 但如果傳入未覆蓋的值會(huì)拋異常。
// 或者明確處理:
// default -> throw new IllegalArgumentException("Invalid day: " + day);
};
}
代碼量顯著減少,-> 語(yǔ)法更直觀,且 switch 表達(dá)式要求覆蓋所有情況(或有 default),更安全。
10. 返回更有意義的類(lèi)型(枚舉或自定義對(duì)象)
避免使用魔法數(shù)字或含義模糊的字符串作為返回碼,應(yīng)返回定義清晰的枚舉或包含狀態(tài)和信息的自定義結(jié)果對(duì)象。
反面教材 :
public int processOrder(Order order) {
if (order == null) return -1; // -1 代表失敗
if (!checkInventory(order)) return 1; // 1 代表庫(kù)存不足
// ... 處理 ...
if (!paymentSuccess(order)) return 2; // 2 代表支付失敗
return 0; // 0 代表成功
}
// 調(diào)用方
int resultCode = processOrder(myOrder);
if (resultCode == 0) { ... }
else if (resultCode == 1) { ... } // 難以理解和維護(hù)
推薦寫(xiě)法 :
public enum OrderStatus { SUCCESS, FAILED_NULL_ORDER, FAILED_INVENTORY, FAILED_PAYMENT }
public OrderStatus processOrder(Order order) {
if (order == null) return OrderStatus.FAILED_NULL_ORDER;
if (!checkInventory(order)) return OrderStatus.FAILED_INVENTORY;
// ... 處理 ...
if (!paymentSuccess(order)) return OrderStatus.FAILED_PAYMENT;
return OrderStatus.SUCCESS;
}
// 調(diào)用方
OrderStatus status = processOrder(myOrder);
if (status == OrderStatus.SUCCESS) { ... }
else if (status == OrderStatus.FAILED_INVENTORY) { ... } // 清晰易懂
返回類(lèi)型本身就攜帶了業(yè)務(wù)含義,代碼自解釋?zhuān)子诰S護(hù)和擴(kuò)展。
11. 注意 finally 塊中的 return(陷阱?。?/h2>
盡量避免在 finally 塊中使用 return。
它會(huì)覆蓋 try 或 catch 塊中的 return 或拋出的異常,可能導(dǎo)致非預(yù)期的行為和難以追蹤的 Bug。
反面教材 (極不推薦):
public int trickyReturn() {
try {
System.out.println("Trying...");
// 假設(shè)這里發(fā)生異?;蛘7祷?1
// throw new RuntimeException("Oops!");
return 1;
} catch (Exception e) {
System.out.println("Caught exception");
return 2; // 試圖在 catch 中返回 2
} finally {
System.out.println("Finally block");
return 3; // finally 中的 return 會(huì)覆蓋前面的所有返回/異常!
}
// 這個(gè)方法最終會(huì)返回 3,即使 try 或 catch 中有 return 或拋出異常
}
finally 的主要目的是資源清理(如關(guān)閉流、釋放鎖),而不是返回值。
在這里 return 會(huì)讓程序行為變得詭異。
推薦寫(xiě)法 :
public int cleanReturn() {
int result = -1; // 默認(rèn)值或錯(cuò)誤碼
Connection conn = null;
try {
conn = getConnection();
// ... 使用 conn 操作 ...
result = 1; // 操作成功
return result; // 在 try 中返回
} catch (SQLException e) {
System.err.println("Database error: " + e.getMessage());
result = -2; // 數(shù)據(jù)庫(kù)錯(cuò)誤碼
return result; // 在 catch 中返回
} finally {
// 只做清理工作
if (conn != null) {
try {
conn.close();
System.out.println("Connection closed.");
} catch (SQLException e) {
System.err.println("Failed to close connection: " + e.getMessage());
}
}
// 不要在 finally 中 return
}
}
finally 專(zhuān)注于它的本職工作——資源清理,讓返回值邏輯在 try 和 catch 中清晰地處理。
結(jié)尾
return 雖小,五臟俱全。
一切的目的都是讓代碼更加優(yōu)雅,邏輯更加清晰。
這些并非什么高深的理論,更多的是在日常寫(xiě)代碼時(shí),對(duì)可讀性、簡(jiǎn)潔性和健壯性的追求。
到此這篇關(guān)于11個(gè)值得借鑒的Java return寫(xiě)法分享的文章就介紹到這了,更多相關(guān)Java return寫(xiě)法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Java如何實(shí)現(xiàn)與JS相同的Des加解密算法
這篇文章主要介紹了如何在Java中實(shí)現(xiàn)與JavaScript相同的DES(Data Encryption Standard)加解密算法,確保在兩個(gè)平臺(tái)之間可以無(wú)縫地傳遞加密信息,希望對(duì)大家有一定的幫助2025-04-04
Springboot整合spring-boot-starter-data-elasticsearch的過(guò)程
本文詳細(xì)介紹了Springboot整合spring-boot-starter-data-elasticsearch的過(guò)程,包括版本要求、依賴(lài)添加、實(shí)體類(lèi)添加、索引的名稱(chēng)、分片、副本設(shè)置等,同時(shí),還介紹了如何使用ElasticsearchRepository類(lèi)進(jìn)行增刪改查操作2024-10-10
zookeeper實(shí)戰(zhàn)之實(shí)現(xiàn)分布式鎖的方法
Zookeeper實(shí)現(xiàn)分布式鎖比Redis簡(jiǎn)單,Zookeeper有一個(gè)特性,多個(gè)線程在Zookeeper里創(chuàng)建同一個(gè)節(jié)點(diǎn)時(shí),只有一個(gè)線程執(zhí)行成功,Zookeeper主要是利用臨時(shí)有序節(jié)點(diǎn)這一特性實(shí)現(xiàn)分布式鎖,感興趣的朋友跟隨小編一起學(xué)習(xí)吧2022-11-11
SpringMVC將請(qǐng)求和響應(yīng)的數(shù)據(jù)轉(zhuǎn)換為JSON格式的幾種方式
這篇文章主要給大家介紹餓了SpringMVC將請(qǐng)求和響應(yīng)的數(shù)據(jù)轉(zhuǎn)換為JSON格式的幾種方式,文中通過(guò)代碼示例和圖文結(jié)合給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-11-11
java實(shí)現(xiàn)數(shù)字轉(zhuǎn)大寫(xiě)的方法
這篇文章主要介紹了 java實(shí)現(xiàn)數(shù)字轉(zhuǎn)大寫(xiě)的方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10
springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù)
這篇文章主要介紹了springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
java基于RMI遠(yuǎn)程過(guò)程調(diào)用詳解
這篇文章主要為大家詳細(xì)介紹了java基于RMI遠(yuǎn)程過(guò)程調(diào)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Java實(shí)現(xiàn)快速排序算法(Quicktsort)
這篇文章主要介紹了Java實(shí)現(xiàn)快速排序算法(Quicktsort),有需要的朋友可以參考一下2013-12-12

