多年Java老手總結的這幾個神仙技巧你用過嗎
前言
如果你也是從 public static void main(String[] args) 和 System.out.println() 開始Java生涯的,那也是Java老油條了。在日常的業(yè)務開發(fā)中,我們每天都在寫著增刪改查的邏輯,有時候會覺得Java有點笨重,語法有點啰嗦。
但其實,Java在不斷進化。從我們熟悉的Java 8到現(xiàn)在的Java 25,它多了很多實用的新特性和一些不為人知的老技巧。用好它們,不僅能讓代碼更簡潔,還能在同事面前小小地秀一下。

下面就聊幾個我自己在工作中覺得特別好用的技巧,看看你用過幾個。
用枚舉(Enum)干點正事
很多人對枚舉的印象還停留在定義一組常量,比如 MALE, FEMALE。但其實,枚舉遠比這強大,它甚至可以擁有自己的方法和實現(xiàn),非常適合用來替代一堆 if-else 或者 switch 的策略邏輯。
舉個例子,假設我們有不同的會員等級,需要計算折扣后的價格:
// 利用枚舉實現(xiàn)不同會員的折扣策略
public enum MemberType {
REGULAR {
@Override
public double applyDiscount(double price) {
return price * 0.98; // 普通會員98折
}
},
VIP {
@Override
public double applyDiscount(double price) {
return price * 0.9; // VIP會員9折
}
},
PREMIUM {
@Override
public double applyDiscount(double price) {
return price * 0.8; // 高級會員8折
}
};
public abstract double applyDiscount(double price);
}
// 使用起來非常清晰
public class PriceCalculator {
public static void main(String[] args) {
double originalPrice = 100.0;
double vipPrice = MemberType.VIP.applyDiscount(originalPrice);
System.out.println("VIP會員價:" + vipPrice); // 輸出:VIP會員價:90.0
}
}這樣寫,每種會員的折扣邏輯都封裝在自己的枚舉實例里,代碼清晰,擴展起來也方便。以后要加新的會員等級,只需要添加一個新的枚舉實例就行,完全符合開閉原則。
用記錄(Record)告別樣板代碼
自從Java 16引入了 Record 類型,我寫DTO(數(shù)據(jù)傳輸對象)的幸福感直線上升。以前為了定義一個簡單的數(shù)據(jù)載體,得手動寫一堆的 getter, setter, equals(), hashCode() 和 toString(),或者依賴Lombok。
現(xiàn)在,一行代碼就夠了。
// 以前的寫法
// public class User {
// private final String username;
// private final String email;
// // ... 一大堆 getter, equals, hashCode, toString ...
// }
// 現(xiàn)在用Record
public record UserProfile(String username, String email) {}
// 使用
public class Main {
public static void main(String[] args) {
UserProfile user = new UserProfile("dev_user", "user@example.com");
System.out.println(user.username()); // 直接調(diào)用,像方法一樣
System.out.println(user); // 自帶了很好的toString()實現(xiàn)
}
}編譯器會自動幫你生成所有必需的方法,代碼瞬間清爽了很多。
類型安全的ID,防止傳錯參數(shù)
在業(yè)務代碼里,經(jīng)常會用 Long 或者 String 來表示各種ID,比如 userId, orderId, productId。這樣做的風險是,方法的參數(shù)很容易傳混。
// 很容易寫錯的調(diào)用
public void processOrder(Long userId, Long orderId) {
// ...
}
// 調(diào)用時可能不小心把兩個ID搞反
processOrder(orderId, userId); // 編譯器不會報錯,但邏輯全錯了那就可以利用 Record (或者普通類) 來給ID一層包裝,增加類型安全性,讓編譯器在編碼階段就幫我們發(fā)現(xiàn)錯誤。
public record UserId(long value) {}
public record OrderId(long value) {}
public class OrderService {
public void processOrder(UserId userId, OrderId orderId) {
System.out.println("處理用戶 " + userId.value() + " 的訂單 " + orderId.value());
}
public static void main(String[] args) {
OrderService service = new OrderService();
UserId userId = new UserId(1001L);
OrderId orderId = new OrderId(9527L);
service.processOrder(userId, orderId); // 正確
// service.processOrder(orderId, userId); // 這行代碼會直接編譯失敗,安全!
}
}這個小改動能避免很多難以排查的線上問題。
用 Stream API 告別 for 循環(huán)
從Java 8開始,Stream API 就已經(jīng)是處理集合的標配了。如果還在用 for 循環(huán)和一堆 if 來做篩選和轉換,那代碼讀起來會很費勁。Stream API可以用一種更聲明式、更流暢的方式來操作數(shù)據(jù)。
比如,我們要從一堆產(chǎn)品里,篩選出價格大于500的,然后取出它們的名字:
import java.util.List;
import java.util.stream.Collectors;
public class StreamDemo {
record Product(String name, double price) {}
public static void main(String[] args) {
List<Product> products = List.of(
new Product("筆記本電腦", 5999.0),
new Product("鼠標", 299.0),
new Product("機械鍵盤", 799.0)
);
// 使用Stream API
List<String> expensiveProductNames = products.stream()
.filter(p -> p.price() > 500.0) // 篩選價格
.map(Product::name) // 提取名稱
.collect(Collectors.toList()); // 收集成列表
System.out.println(expensiveProductNames); // 輸出: [筆記本電腦, 機械鍵盤]
}
}鏈式調(diào)用,一氣呵成,代碼的意圖一目了然。
用文本塊(Text Blocks)優(yōu)雅地寫多行字符串
以前在Java代碼里拼接SQL或者JSON字符串,簡直是一場災難,充滿了 + 號和 \n 轉義符,可讀性極差。Java 15引入的文本塊(Text Blocks)徹底解決了這個問題。
看看對比:
public class TextBlockDemo {
public static void main(String[] args) {
// 以前的方式,又丑又容易出錯
String oldJson = "{\n" +
" "name": "Alice",\n" +
" "age": 30\n" +
"}";
// 現(xiàn)在用文本塊,所見即所得
String newJson = """
{
"name": "Alice",
"age": 30
}
""";
System.out.println(oldJson.equals(newJson)); // 輸出: true
}
}用三個雙引號 """ 包起來,字符串的格式就能完全保留,代碼干凈多了。
還在用!= null?試試Optional
空指針異常(NullPointerException)應該不少 Java 開發(fā)者都很熟了。為了避免它,我們代碼里堆滿了 if (obj != null) 的判斷。Optional 的出現(xiàn)就是為了更優(yōu)雅地處理可能為空的情況。
import java.util.Optional;
public class UserRepository {
// 模擬從數(shù)據(jù)庫查找用戶
public Optional<String> findUserNameById(long id) {
if (id == 1L) {
return Optional.of("Alice");
}
return Optional.empty(); // 表示沒找到
}
public static void main(String[] args) {
UserRepository repo = new UserRepository();
// 優(yōu)雅地處理
repo.findUserNameById(1L)
.ifPresentOrElse(
name -> System.out.println("找到用戶:" + name),
() -> System.out.println("用戶不存在")
);
// 獲取值,如果不存在則提供一個默認值
String userName = repo.findUserNameById(2L).orElse("默認用戶");
System.out.println("查詢ID為2的用戶:" + userName);
}
}用 Optional 不僅能讓代碼意圖更明確(這個方法的返回值可能為空),還能通過鏈式調(diào)用寫出更流暢的代碼。
管理好Java環(huán)境,才能玩轉新特性
看到這里,你可能已經(jīng)注意到,上面提到的不少特性都和Java版本有關。比如 Record 是Java 16的,文本塊是Java 15的,ifPresentOrElse 是Java 9的。在實際工作中,我們經(jīng)常會遇到這樣的情況:
老項目A還在用穩(wěn)定的Java 8。
新項目B想嘗試Java 17的LTS版本。
自己想學習一下最新的Java 25。
在電腦上同時管理這么多Java版本,配置環(huán)境變量,為不同項目切換JDK,挺讓人破防的。每次切換環(huán)境,都要敲一堆命令,或者在IDE里改來改去,很影響開發(fā)效率。
所以,這時候就需要ServBay。
它本來是一個集成了PHP、Node.js等環(huán)境的Web開發(fā)工具,但我發(fā)現(xiàn)它對Java的支持也做得特別好。最讓我喜歡的一點是,它可以一鍵安裝和管理多個Java版本。我可以同時安裝Java 8、11、17、21等多個版本,它們之間完全隔離,互不干擾。

而且,我還可以為不同的項目指定使用不同的Java版本。比如,可以設置項目A的運行環(huán)境就是Java 8,項目B就是Java 23。這樣一來,在切換項目時,根本不用關心JDK版本的問題,ServBay都幫你自動處理好了。
對于我們Java開發(fā)者來說,這意味著可以把更多精力放在代碼和技術本身,而不是被環(huán)境配置這些瑣事消耗。
總結
Java依然是一門生命力旺盛的語言。學習和使用這些技巧,可以讓我們的代碼質量更高,開發(fā)體驗也更好。而借助像ServBay這樣的工具,又能幫我們輕松搞定復雜的環(huán)境管理問題,讓我們能更專注于寫出優(yōu)秀的代碼。
到此這篇關于多年Java老手總結的幾個神仙技巧的文章就介紹到這了,更多相關Java神仙技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springboot使用hibernate validator校驗方式
hibernate validator提供了一套比較完善、便捷的驗證實現(xiàn)方式。下面小編給大家介紹下springboot使用hibernate validator校驗方式,感興趣的朋友一起看看吧2018-01-01
Mybatis-Plus最優(yōu)化持久層開發(fā)過程
Mybatis-plus(簡稱MP)是一個Mybatis的增強工具,在mybatis的基礎上只做增強不做改變,提高效率,自動生成單表的CRUD功能,這篇文章主要介紹了Mybatis-Plus最優(yōu)化持久層開發(fā),需要的朋友可以參考下2024-07-07
解決springboot bean中大寫的字段返回變成小寫的問題
這篇文章主要介紹了解決springboot bean中大寫的字段返回變成小寫的問題,具有很好的參考價值希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
SpringBoot+Flying Saucer+Thymeleaf實現(xiàn)PDF生成的完整指南
在實際開發(fā)中,PDF生成是常見需求,本文將詳細講解如何基于 Spring Boot + Flying Saucer + Thymeleaf 實現(xiàn) PDF 生成,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下2026-01-01
SpringBoot使用RestTemplate發(fā)送http請求的實操演示
RestTemplate是Spring 框架提供的 ,可用于在應用中調(diào)用 rest 服務,它簡化了與 http 服務的通信方式,統(tǒng)一了 RESTful 的標準,封裝了 http 鏈接,本文給大家介紹了SpringBoot使用RestTemplate發(fā)送http請求的實操演示,需要的朋友可以參考下2024-11-11

