在 Java 開發中,優雅的代碼不僅能提升開發效率,更能降低維護成本、減少線上故障。除了基礎的語法簡化,結合現代 Java 特性與最佳實踐,可實現代碼從 “能用” 到 “好用” 的質變。以下 20 個關鍵技巧,覆蓋語法優化、性能提升、架構設計等多個維度,助力開發者寫出更簡潔、高效、可維護的 Java 代碼。
一、Java 8 + 核心特性深度挖掘
1. 模式匹配進階(Java 16+)
傳統寫法:
if (obj != null && obj instanceof User) {
User user = (User) obj;
if (user.getAge() >= 18) {
// 成年用户邏輯
}
}
if (obj instanceof User user && user.getAge() >= 18) {
// 直接使用校驗後的user對象
}
2. Switch 表達式完整用法(Java 14+)
傳統寫法:
int score = 85;
String grade;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 60) {
grade = "C";
} else {
grade = "D";
}
String grade = switch (score / 10) {
case 10, 9 -> "A";
case 8 -> "B";
case 7, 6 -> "C";
default -> "D";
};
3. 文本塊(Java 15+)
傳統寫法:
String sql = "SELECT id, name, age FROM user " +
"WHERE age > 18 " +
"ORDER BY create_time DESC";
String sql = """
SELECT id, name, age FROM user
WHERE age > 18
ORDER BY create_time DESC
""";
二、Stream API 性能與可讀性雙優
4. 並行流合理運用
傳統循環:
List<Double> results = new ArrayList<>();
for (Data data : largeDataset) {
results.add(complexCalculation(data));
}
List<Double> results = largeDataset.parallelStream()
.map(this::complexCalculation)
.collect(Collectors.toList());
5. Stream 終止操作優化
冗餘寫法:
boolean hasAdult = users.stream()
.filter(u -> u.getAge() >= 18)
.collect(Collectors.toList())
.size() > 0;
boolean hasAdult = users.stream()
.anyMatch(u -> u.getAge() >= 18); // 短路求值,找到匹配即返回
6. Collectors 高級用法
傳統統計:
Map<String, Integer> deptUserCount = new HashMap<>();
for (User user : users) {
String dept = user.getDepartment();
deptUserCount.put(dept, deptUserCount.getOrDefault(dept, 0) + 1);
}
Map<String, Long> deptUserCount = users.stream()
.collect(Collectors.groupingBy(
User::getDepartment,
Collectors.counting() // 分組後直接統計數量
));
三、空值處理終極方案
7. Optional 避免嵌套調用
傳統判空:
String leaderName = null;
if (department != null) {
User leader = department.getLeader();
if (leader != null) {
leaderName = leader.getName();
}
}
String leaderName = Optional.ofNullable(department)
.flatMap(Dept::getLeader) // getLeader返回Optional<User>
.map(User::getName)
.orElse("No Leader");
8. Objects 工具類全面應用
冗餘校驗:
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
List<String> validList = Objects.requireNonNullElseGet(list, Collections::emptyList);
9. 空安全集合與映射
傳統寫法:
List<String> tags = user.getTags();
if (tags == null) {
tags = new ArrayList<>();
}
List<String> tags = Optional.ofNullable(user.getTags())
.orElseGet(List::of); // List.of()創建不可變空集合
四、設計模式簡化與創新
10. 工廠模式 + Lambda
傳統工廠:
interface ProductFactory {
Product create(String type);
}
class ConcreteFactory implements ProductFactory {
@Override
public Product create(String type) {
switch (type) {
case "A": return new ProductA();
case "B": return new ProductB();
default: return new DefaultProduct();
}
}
}
Map<String, Supplier<Product>> productMap = Map.of(
"A", ProductA::new,
"B", ProductB::new,
"default", DefaultProduct::new
);
Product product = productMap.getOrDefault(type, DefaultProduct::new).get();
11. 觀察者模式 + 函數式接口
傳統實現:
interface Observer {
void onEvent(Event event);
}
class EventListener implements Observer {
@Override
public void onEvent(Event event) {
// 事件處理邏輯
}
}
eventSource.addObserver(new EventListener());
eventSource.addListener(event -> {
// 直接編寫事件處理邏輯
});
12. 記錄類(Record)深度應用(Java 16+)
傳統不可變類:
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// 手動編寫getter、equals、hashCode、toString
}
record Point(int x, int y) {} // 自動生成所有必要方法
五、工具類與框架高效集成
13. Lombok 進階註解
傳統日誌與構建:
public class OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
private final OrderRepository repo;
private final PaymentService paymentService;
// 構造方法
public OrderService(OrderRepository repo, PaymentService paymentService) {
this.repo = repo;
this.paymentService = paymentService;
}
// 日誌打印
public void createOrder(Order order) {
logger.info("Creating order: {}", order.getId());
// 業務邏輯
}
}
@Slf4j // 自動生成日誌對象
@RequiredArgsConstructor // 為final字段生成構造方法
public class OrderService {
private final OrderRepository repo;
private final PaymentService paymentService;
public void createOrder(Order order) {
log.info("Creating order: {}", order.getId()); // 直接使用log對象
// 業務邏輯
}
}
14. Guava 工具類進階
傳統緩存實現:
Map<String, Data> cache = new HashMap<>();
// 手動實現緩存過期、加載邏輯
LoadingCache<String, Data> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<>() {
@Override
public Data load(String key) {
return fetchDataFromDB(key); // 緩存未命中時自動加載
}
});
// 使用緩存
Data data = cache.get("key");
15. Spring Boot 簡化配置
傳統 Spring 配置:
@Configuration
public class AppConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
// 直接使用@RestClientTest或自動配置,無需手動聲明Bean
@RestController
public class ApiController {
private final RestTemplate restTemplate;
// 構造方法注入(Spring 4.3+自動支持)
public ApiController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
}
六、性能優化關鍵技巧
16. 不可變對象優先
傳統可變類:
public class User {
private String name;
private int age;
// getter和setter
}
public final class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = Objects.requireNonNull(name);
this.age = age;
}
// 僅提供getter,無setter
}
17. 字符串操作優化
冗餘寫法:
String result = "";
for (String item : items) {
result += item + ",";
}
// 去除末尾逗號
if (!result.isEmpty()) {
result = result.substring(0, result.length() - 1);
}
String result = String.join(",", items); // 自動拼接,無末尾分隔符
18. 集合初始化優化
傳統寫法:
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 已知元素數量,指定初始容量
List<String> list = new ArrayList<>(3);
list.add("a");
list.add("b");
list.add("c");
// 或使用不可變集合(Java 9+)
List<String> immutableList = List.of("a", "b", "c");
七、代碼結構與可讀性優化
19. 方法拆分原則
複雜方法:
public void processOrder(Order order) {
// 1. 校驗訂單
if (order == null || order.getItems().isEmpty()) {
throw new IllegalArgumentException();
}
// 2. 計算金額
BigDecimal amount = order.getItems().stream()
.map(item -> item.getPrice().multiply(new BigDecimal(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 3. 保存訂單
orderRepository.save(order);
// 4. 發送通知
notificationService.send(order.getUserId(), "訂單已創建");
}
public void processOrder(Order order) {
validateOrder(order);
BigDecimal amount = calculateOrderAmount(order);
saveOrder(order);
sendOrderNotification(order);
}
private void validateOrder(Order order) {
if (order == null || order.getItems().isEmpty()) {
throw new IllegalArgumentException();
}
}
private BigDecimal calculateOrderAmount(Order order) {
return order.getItems().stream()
.map(item -> item.getPrice().multiply(new BigDecimal(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
// 其他輔助方法...
20. 註釋與命名規範
不良示例:
// 計算總和
public BigDecimal calSum(List<Item> is) {
BigDecimal s = BigDecimal.ZERO;
for (Item i : is) {
s = s.add(i.getP().multiply(new BigDecimal(i.getQ())));
}
return s;
}
/**
* 計算訂單商品總金額(單價 × 數量求和)
* @param items 訂單商品列表
* @return 總金額
*/
public BigDecimal calculateTotalAmount(List<Item> items) {
return items.stream()
.map(item -> item.getPrice().multiply(new BigDecimal(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
總結