本文目录导读:

我为您提供一个Java技术升级的完整实战案例,展示从传统代码到现代Java特性的演进过程。
场景:用户订单管理系统
让我们通过一个订单管理系统的升级,展示Java技术的演进。
版本1:传统Java 8实现(基础版)
// 订单实体类
public class Order {
private Long id;
private String customerName;
private BigDecimal amount;
private LocalDateTime createTime;
private OrderStatus status;
private List<OrderItem> items;
// 构造函数、getter、setter省略
public enum OrderStatus {
PENDING, PAID, SHIPPED, COMPLETED, CANCELLED
}
}
// 订单服务 - 传统写法
public class OrderServiceImpl implements OrderService {
private final OrderRepository orderRepository;
public OrderServiceImpl(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public Order createOrder(OrderRequest request) {
// 手动校验
if (request == null) {
throw new IllegalArgumentException("请求不能为空");
}
if (request.getCustomerName() == null || request.getCustomerName().isEmpty()) {
throw new IllegalArgumentException("客户名称不能为空");
}
if (request.getAmount() == null || request.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("订单金额必须大于0");
}
Order order = new Order();
order.setCustomerName(request.getCustomerName());
order.setAmount(request.getAmount());
order.setStatus(OrderStatus.PENDING);
order.setCreateTime(LocalDateTime.now());
// 计算订单总额
BigDecimal total = BigDecimal.ZERO;
for (OrderItem item : request.getItems()) {
BigDecimal itemTotal = item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
total = total.add(itemTotal);
}
order.setAmount(total);
return orderRepository.save(order);
}
@Override
public List<Order> getPaidOrders() {
List<Order> allOrders = orderRepository.findAll();
List<Order> paidOrders = new ArrayList<>();
for (Order order : allOrders) {
if (order.getStatus() == OrderStatus.PAID) {
paidOrders.add(order);
}
}
return paidOrders;
}
@Override
public BigDecimal calculateTotalAmount(List<Order> orders) {
BigDecimal total = BigDecimal.ZERO;
for (Order order : orders) {
if (order.getStatus() != OrderStatus.CANCELLED) {
total = total.add(order.getAmount());
}
}
return total;
}
}
版本2:Java 11升级(Stream + Optional + 接口默认方法)
// 升级:使用Stream API和Optional
@Service
@Slf4j
public class OrderServiceV2 {
private final OrderRepository orderRepository;
public OrderServiceV2(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
// 使用Optional和Stream提升代码质量
public Optional<Order> findOrderById(Long id) {
return orderRepository.findById(id);
}
public List<Order> getPaidOrders() {
return orderRepository.findAll().stream()
.filter(order -> order.getStatus() == OrderStatus.PAID)
.collect(Collectors.toList());
}
public List<Order> getTopOrders(int limit) {
return orderRepository.findAll().stream()
.filter(order -> order.getStatus() != OrderStatus.CANCELLED)
.sorted(Comparator.comparing(Order::getAmount).reversed())
.limit(limit)
.collect(Collectors.toList());
}
public Map<OrderStatus, List<Order>> groupByStatus() {
return orderRepository.findAll().stream()
.collect(Collectors.groupingBy(Order::getStatus));
}
public BigDecimal calculateTotalAmount(List<Order> orders) {
return orders.stream()
.filter(order -> order.getStatus() != OrderStatus.CANCELLED)
.map(Order::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
// 使用Objects.requireNonNull和var
public Order createOrder(OrderRequest request) {
Objects.requireNonNull(request, "请求不能为空");
// 使用增强的Optional处理
String customerName = Optional.ofNullable(request.getCustomerName())
.filter(name -> !name.isEmpty())
.orElseThrow(() -> new IllegalArgumentException("客户名称不能为空"));
var order = new Order();
order.setCustomerName(customerName);
order.setCreateTime(LocalDateTime.now());
order.setStatus(OrderStatus.PENDING);
// 使用Stream计算
var totalAmount = request.getItems().stream()
.map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
order.setAmount(totalAmount);
return orderRepository.save(order);
}
}
版本3:Java 17升级(Record + 密封类 + Pattern Matching)
// 使用Record定义DTO
public record OrderResponse(
Long id,
String customerName,
BigDecimal amount,
LocalDateTime createTime,
String status
) {
// 紧凑构造函数
public OrderResponse {
Objects.requireNonNull(customerName, "客户名称不能为空");
if (amount.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("金额不能为负");
}
}
// 静态工厂方法
public static OrderResponse from(Order order) {
return new OrderResponse(
order.getId(),
order.getCustomerName(),
order.getAmount(),
order.getCreateTime(),
order.getStatus().name()
);
}
// 自定义方法
public String displayInfo() {
return String.format("订单#%d - %s: ¥%.2f", id, customerName, amount);
}
}
// 使用密封类定义订单事件
public sealed interface OrderEvent
permits OrderCreated, OrderPaid, OrderShipped, OrderCancelled {
Long orderId();
LocalDateTime timestamp();
default String eventDescription() {
return "订单事件: " + orderId();
}
}
record OrderCreated(Long orderId, LocalDateTime timestamp, BigDecimal amount)
implements OrderEvent {}
record OrderPaid(Long orderId, LocalDateTime timestamp, String paymentMethod)
implements OrderEvent {}
record OrderShipped(Long orderId, LocalDateTime timestamp, String trackingNumber)
implements OrderEvent {}
record OrderCancelled(Long orderId, LocalDateTime timestamp, String reason)
implements OrderEvent {}
// 使用Pattern Matching for Switch(Java 17预览,Java 21正式)
@Service
@Slf4j
public class OrderServiceV3 {
private final OrderRepository orderRepository;
public OrderServiceV3(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
public String handleOrderEvent(OrderEvent event) {
// Switch表达式 + Pattern Matching
return switch (event) {
case OrderCreated created ->
String.format("新订单创建: #%d, 金额 ¥%.2f",
created.orderId(), created.amount());
case OrderPaid paid ->
String.format("订单已支付: #%d, 支付方式 %s",
paid.orderId(), paid.paymentMethod());
case OrderShipped shipped ->
String.format("订单已发货: #%d, 运单号 %s",
shipped.orderId(), shipped.trackingNumber());
case OrderCancelled cancelled ->
String.format("订单已取消: #%d, 原因 %s",
cancelled.orderId(), cancelled.reason());
};
}
// 使用文本块和增强的String方法
public String generateOrderReport() {
return """
========================================
订单统计报告
生成时间: %s
========================================
总订单数: %d
已完成: %d
待处理: %d
已取消: %d
总金额: ¥%.2f
========================================
""".formatted(
LocalDateTime.now(),
orderRepository.count(),
countByStatus(OrderStatus.COMPLETED),
countByStatus(OrderStatus.PENDING),
countByStatus(OrderStatus.CANCELLED),
getTotalAmount()
);
}
private long countByStatus(OrderStatus status) {
return orderRepository.findAll().stream()
.filter(o -> o.getStatus() == status)
.count();
}
private BigDecimal getTotalAmount() {
return orderRepository.findAll().stream()
.map(Order::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
版本4:Java 21+ 完整现代实现
// 使用虚拟线程、结构化并发等新特性
@Service
public class OrderServiceV4 {
private final OrderRepository orderRepository;
private final PaymentService paymentService;
private final InventoryService inventoryService;
private final NotificationService notificationService;
public OrderServiceV4(OrderRepository orderRepository,
PaymentService paymentService,
InventoryService inventoryService,
NotificationService notificationService) {
this.orderRepository = orderRepository;
this.paymentService = paymentService;
this.inventoryService = inventoryService;
this.notificationService = notificationService;
}
// 使用虚拟线程并行处理
public CompletableFuture<OrderProcessResult> processOrderParallel(Order order) {
return CompletableFuture.supplyAsync(() -> {
// 并行执行多个独立任务
var paymentFuture = CompletableFuture
.supplyAsync(() -> paymentService.processPayment(order));
var inventoryFuture = CompletableFuture
.supplyAsync(() -> inventoryService.reserveStock(order));
var notificationFuture = CompletableFuture
.supplyAsync(() -> notificationService.sendConfirmation(order));
// 等待所有任务完成
return CompletableFuture.allOf(paymentFuture, inventoryFuture, notificationFuture)
.thenApply(v -> new OrderProcessResult(
paymentFuture.join(),
inventoryFuture.join(),
notificationFuture.join()
)).join();
}, Executors.newVirtualThreadPerTaskExecutor());
}
// 使用Stream的增强特性
public Optional<OrderSummary> getSummary(OrderStatus... statuses) {
return orderRepository.findAll().stream()
.filter(order -> Arrays.asList(statuses).contains(order.getStatus()))
.map(this::toSummary)
.reduce((s1, s2) -> new OrderSummary(
s1.totalOrders() + s2.totalOrders(),
s1.totalAmount().add(s2.totalAmount())
));
}
private OrderSummary toSummary(Order order) {
return new OrderSummary(1, order.getAmount());
}
// 使用Records作为局部变量
public void checkOrderValidity(Order order) {
record ValidationResult(boolean valid, List<String> errors) {}
var result = new ValidationResult(true, new ArrayList<>());
// 业务逻辑检查
if (order.getItems().isEmpty()) {
result = new ValidationResult(false, List.of("订单没有商品"));
}
if (order.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
result = new ValidationResult(false, List.of("订单金额无效"));
}
if (!result.valid()) {
throw new IllegalArgumentException(String.join(", ", result.errors()));
}
}
}
// 使用自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retryable {
int maxAttempts() default 3;
long delayMs() default 1000;
Class<? extends Throwable>[] retryFor() default {Exception.class};
}
// AOP实现重试机制(简化示例)
@Aspect
@Component
public class RetryAspect {
@Around("@annotation(retryable)")
public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable)
throws Throwable {
int maxAttempts = retryable.maxAttempts();
long delayMs = retryable.delayMs();
Throwable lastException = null;
for (int attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return joinPoint.proceed();
} catch (Throwable ex) {
lastException = ex;
log.warn("执行失败,第{}次尝试", attempt, ex);
if (attempt < maxAttempts) {
try {
Thread.sleep(delayMs);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw ex;
}
}
}
}
throw lastException;
}
}
测试代码示例
public class OrderServiceTest {
@Test
void testOrderProcessing() {
// 测试V3版本的Pattern Matching
OrderServiceV3 serviceV3 = new OrderServiceV3(repository);
var event = new OrderCreated(1L, LocalDateTime.now(), BigDecimal.valueOf(199.99));
assertEquals("新订单创建: #1, 金额 ¥199.99", serviceV3.handleOrderEvent(event));
}
@Test
void testRecordResponse() {
OrderResponse response = new OrderResponse(
1L, "张三", BigDecimal.valueOf(99.99),
LocalDateTime.now(), "PENDING"
);
assertTrue(response.displayInfo().contains("张三"));
assertEquals("PENDING", response.status());
}
@Test
void testParallelProcessing() {
OrderServiceV4 serviceV4 = new OrderServiceV4(
repository, paymentService, inventoryService, notificationService
);
Order order = createTestOrder();
CompletableFuture<OrderProcessResult> future =
serviceV4.processOrderParallel(order);
assertNotNull(future.join());
}
}
| 特性 | Java 8 | Java 11 | Java 17 | Java 21 |
|---|---|---|---|---|
| 类型推断 | 无 | var | var | var + Record patterns |
| 数据类 | 普通类+getter/setter | 普通类+Lombok | Record | Record + Sealed |
| 集合处理 | 循环 | Stream API | Stream优化 | Stream增强+虚拟线程 |
| 可选处理 | null检查 | Optional | Optional+record | Pattern matching |
| 并发处理 | 线程池 | CompletableFuture | CompletableFuture优化 | 虚拟线程+结构化并发 |
| 字符串处理 | 字符串拼接 | 基础方法 | 文本块+formatted | 增强String方法 |
关键升级亮点
- 代码简洁性:Record减少模板代码
- 类型安全性:密封类提供受限继承
- 性能提升:虚拟线程处理高并发
- 可读性提高:Pattern Matching和Stream简化逻辑
- API设计优化:Optional、Stream等函数式接口
这个案例展示了如何通过升级Java版本,逐步采用现代特性来改进代码质量、性能和可维护性。