JDK 17 实战系列(第5期):开发工具与API增强详解

前言

欢迎来到JDK 17深度解析系列的第五期!本期我们将深入探讨JDK 17在开发工具、API增强和开发体验方面的重大改进。从强大的语言特性到实用的API增强,从开发工具的升级到调试体验的优化,JDK 17为Java开发者带来了前所未有的开发效率提升。

📚 本期概览

  • 现代语言特性 - Pattern Matching、Sealed Classes等新特性
  • 核心API增强 - Stream、Optional、Collections等API改进
  • 开发工具升级 - 编译器、调试器、性能分析工具
  • HTTP客户端API - 全新的现代化HTTP处理
  • 文本处理增强 - 字符串处理和文本块功能
  • 数据处理优化 - JSON、XML处理能力提升

一、现代语言特性深度解析

1.1 Pattern Matching增强

JDK 17显著增强了模式匹配能力,让代码更加简洁和类型安全。

instanceof的模式匹配

java 复制代码
/**
 * instanceof模式匹配示例
 */
public class PatternMatchingExamples {
    
    /**
     * 传统的instanceof使用方式
     */
    public String processObjectOldWay(Object obj) {
        if (obj instanceof String) {
            String str = (String) obj;  // 需要显式转换
            return str.toUpperCase();
        } else if (obj instanceof Number) {
            Number num = (Number) obj;  // 需要显式转换
            return "Number: " + num.doubleValue();
        } else if (obj instanceof List) {
            List<?> list = (List<?>) obj;  // 需要显式转换
            return "List size: " + list.size();
        }
        return "Unknown type";
    }
    
    /**
     * JDK 17的模式匹配方式 - 简洁且安全
     */
    public String processObjectNewWay(Object obj) {
        if (obj instanceof String str) {
            return str.toUpperCase();
        } else if (obj instanceof Number num) {
            return "Number: " + num.doubleValue();
        } else if (obj instanceof List<?> list) {
            return "List size: " + list.size();
        }
        return "Unknown type";
    }
    
    /**
     * 复杂的模式匹配示例
     */
    public String analyzeData(Object data) {
        return switch (data) {
            case null -> "No data";
            case String str when str.isEmpty() -> "Empty string";
            case String str when str.length() > 100 -> 
                "Long string: " + str.substring(0, 100) + "...";
            case String str -> "String: " + str;
            case Integer i when i < 0 -> "Negative integer: " + i;
            case Integer i when i > 1000 -> "Large integer: " + i;
            case Integer i -> "Integer: " + i;
            case List<?> list when list.isEmpty() -> "Empty list";
            case List<?> list -> "List with " + list.size() + " items";
            case Map<?, ?> map -> "Map with " + map.size() + " entries";
            default -> "Unknown type: " + data.getClass().getSimpleName();
        };
    }
    
    /**
     * 树结构处理的模式匹配
     */
    public abstract static class TreeNode {
        public abstract int getValue();
    }
    
    public static class Leaf extends TreeNode {
        private final int value;
        
        public Leaf(int value) { this.value = value; }
        
        @Override
        public int getValue() { return value; }
    }
    
    public static class Branch extends TreeNode {
        private final TreeNode left;
        private final TreeNode right;
        
        public Branch(TreeNode left, TreeNode right) {
            this.left = left;
            this.right = right;
        }
        
        public TreeNode getLeft() { return left; }
        public TreeNode getRight() { return right; }
        
        @Override
        public int getValue() {
            return left.getValue() + right.getValue();
        }
    }
    
    /**
     * 使用模式匹配处理树结构
     */
    public int calculateTreeDepth(TreeNode node) {
        if (node instanceof Leaf leaf) {
            return 1;
        } else if (node instanceof Branch branch) {
            return 1 + Math.max(
                calculateTreeDepth(branch.getLeft()),
                calculateTreeDepth(branch.getRight())
            );
        }
        throw new IllegalArgumentException("Unknown node type");
    }
    
    /**
     * 高级模式匹配 - 处理嵌套结构
     */
    public String analyzeNestedStructure(Object obj) {
        return switch (obj) {
            case List<?> list when list.size() == 1 && list.get(0) instanceof String ->
                "Single string list: " + list.get(0);
            
            case List<?> list when list.stream().allMatch(item -> item instanceof Number) ->
                "Numeric list with sum: " + list.stream()
                    .mapToDouble(item -> ((Number) item).doubleValue())
                    .sum();
            
            case Map<?, ?> map when map.containsKey("type") && 
                                   map.get("type").equals("user") ->
                "User map: " + map.get("name");
            
            case String str when str.matches("\\d{4}-\\d{2}-\\d{2}") ->
                "Date string: " + str;
            
            case String str when str.startsWith("http") ->
                "URL: " + str;
                
            default -> "Unrecognized structure";
        };
    }
}

1.2 Sealed Classes (密封类)

密封类提供了更精确的继承控制和更好的模式匹配支持。

密封类的设计与使用

java 复制代码
/**
 * 密封类示例 - 几何图形
 */
public abstract sealed class Shape 
    permits Circle, Rectangle, Triangle {
    
    protected final double area;
    
    protected Shape(double area) {
        this.area = area;
    }
    
    public double getArea() {
        return area;
    }
    
    // 使用模式匹配的抽象方法
    public abstract String getDescription();
}

/**
 * 圆形 - final类,不能再被继承
 */
public final class Circle extends Shape {
    private final double radius;
    
    public Circle(double radius) {
        super(Math.PI * radius * radius);
        this.radius = radius;
    }
    
    public double getRadius() {
        return radius;
    }
    
    @Override
    public String getDescription() {
        return String.format("Circle with radius %.2f", radius);
    }
}

/**
 * 矩形 - 密封类,只允许特定子类
 */
public sealed class Rectangle extends Shape 
    permits Square {
    
    private final double width;
    private final double height;
    
    public Rectangle(double width, double height) {
        super(width * height);
        this.width = width;
        this.height = height;
    }
    
    public double getWidth() { return width; }
    public double getHeight() { return height; }
    
    @Override
    public String getDescription() {
        return String.format("Rectangle %.2f x %.2f", width, height);
    }
}

/**
 * 正方形 - Rectangle的final子类
 */
public final class Square extends Rectangle {
    
    public Square(double side) {
        super(side, side);
    }
    
    public double getSide() {
        return getWidth();
    }
    
    @Override
    public String getDescription() {
        return String.format("Square with side %.2f", getSide());
    }
}

/**
 * 三角形 - 非密封类,可以自由继承
 */
public non-sealed class Triangle extends Shape {
    private final double base;
    private final double height;
    
    public Triangle(double base, double height) {
        super(0.5 * base * height);
        this.base = base;
        this.height = height;
    }
    
    public double getBase() { return base; }
    public double getHeight() { return height; }
    
    @Override
    public String getDescription() {
        return String.format("Triangle with base %.2f and height %.2f", base, height);
    }
}

/**
 * 等腰三角形 - Triangle的子类(因为Triangle是non-sealed的)
 */
public class IsoscelesTriangle extends Triangle {
    
    public IsoscelesTriangle(double base, double height) {
        super(base, height);
    }
    
    @Override
    public String getDescription() {
        return "Isosceles " + super.getDescription();
    }
}

/**
 * 几何计算器 - 展示密封类的模式匹配优势
 */
public class GeometryCalculator {
    
    /**
     * 计算周长 - 编译器能确保所有情况都被覆盖
     */
    public double calculatePerimeter(Shape shape) {
        return switch (shape) {
            case Circle circle -> 2 * Math.PI * circle.getRadius();
            case Rectangle rect -> 2 * (rect.getWidth() + rect.getHeight());
            case Triangle triangle -> {
                // 对于三角形,我们需要更多信息来计算周长
                // 这里假设是直角三角形
                double base = triangle.getBase();
                double height = triangle.getHeight();
                double hypotenuse = Math.sqrt(base * base + height * height);
                yield base + height + hypotenuse;
            }
            // 注意:不需要default分支,编译器知道所有情况都被覆盖了
        };
    }
    
    /**
     * 获取形状类型描述
     */
    public String getShapeType(Shape shape) {
        return switch (shape) {
            case Circle c -> "圆形";
            case Square s -> "正方形";
            case Rectangle r -> "矩形";
            case IsoscelesTriangle it -> "等腰三角形";
            case Triangle t -> "三角形";
        };
    }
    
    /**
     * 比较两个形状
     */
    public String compareShapes(Shape shape1, Shape shape2) {
        return switch (shape1) {
            case Circle c1 -> switch (shape2) {
                case Circle c2 -> String.format("两个圆形,半径比:%.2f", 
                    c1.getRadius() / c2.getRadius());
                case Rectangle r2 -> "圆形与矩形比较";
                case Triangle t2 -> "圆形与三角形比较";
            };
            
            case Rectangle r1 -> switch (shape2) {
                case Circle c2 -> "矩形与圆形比较";
                case Rectangle r2 -> String.format("两个矩形,面积比:%.2f", 
                    r1.getArea() / r2.getArea());
                case Triangle t2 -> "矩形与三角形比较";
            };
            
            case Triangle t1 -> switch (shape2) {
                case Circle c2 -> "三角形与圆形比较";
                case Rectangle r2 -> "三角形与矩形比较";
                case Triangle t2 -> String.format("两个三角形,面积比:%.2f", 
                    t1.getArea() / t2.getArea());
            };
        };
    }
}

/**
 * 状态机模式的密封类应用
 */
public abstract sealed class ConnectionState 
    permits Disconnected, Connecting, Connected, Reconnecting, Failed {
    
    public abstract String getDisplayName();
    public abstract boolean canTransitionTo(ConnectionState newState);
}

public final class Disconnected extends ConnectionState {
    @Override
    public String getDisplayName() { return "断开连接"; }
    
    @Override
    public boolean canTransitionTo(ConnectionState newState) {
        return newState instanceof Connecting;
    }
}

public final class Connecting extends ConnectionState {
    @Override
    public String getDisplayName() { return "连接中"; }
    
    @Override
    public boolean canTransitionTo(ConnectionState newState) {
        return newState instanceof Connected || 
               newState instanceof Failed ||
               newState instanceof Disconnected;
    }
}

public final class Connected extends ConnectionState {
    @Override
    public String getDisplayName() { return "已连接"; }
    
    @Override
    public boolean canTransitionTo(ConnectionState newState) {
        return newState instanceof Disconnected || 
               newState instanceof Reconnecting ||
               newState instanceof Failed;
    }
}

public final class Reconnecting extends ConnectionState {
    @Override
    public String getDisplayName() { return "重新连接中"; }
    
    @Override
    public boolean canTransitionTo(ConnectionState newState) {
        return newState instanceof Connected || 
               newState instanceof Failed ||
               newState instanceof Disconnected;
    }
}

public final class Failed extends ConnectionState {
    private final String reason;
    
    public Failed(String reason) {
        this.reason = reason;
    }
    
    public String getReason() { return reason; }
    
    @Override
    public String getDisplayName() { return "连接失败: " + reason; }
    
    @Override
    public boolean canTransitionTo(ConnectionState newState) {
        return newState instanceof Connecting || 
               newState instanceof Disconnected;
    }
}

/**
 * 连接管理器
 */
public class ConnectionManager {
    private ConnectionState currentState = new Disconnected();
    
    public void transitionTo(ConnectionState newState) {
        if (!currentState.canTransitionTo(newState)) {
            throw new IllegalStateException(
                String.format("无法从 %s 转换到 %s", 
                    currentState.getDisplayName(), 
                    newState.getDisplayName()));
        }
        
        ConnectionState oldState = currentState;
        currentState = newState;
        
        handleStateChange(oldState, newState);
    }
    
    private void handleStateChange(ConnectionState oldState, ConnectionState newState) {
        System.out.printf("状态变化: %s -> %s\n", 
            oldState.getDisplayName(), 
            newState.getDisplayName());
        
        // 使用模式匹配处理状态变化
        switch (newState) {
            case Connecting connecting -> {
                System.out.println("开始建立连接...");
                // 启动连接逻辑
            }
            case Connected connected -> {
                System.out.println("连接建立成功!");
                // 连接成功处理
            }
            case Failed failed -> {
                System.out.println("连接失败: " + failed.getReason());
                // 失败处理逻辑
            }
            case Reconnecting reconnecting -> {
                System.out.println("尝试重新连接...");
                // 重连逻辑
            }
            case Disconnected disconnected -> {
                System.out.println("连接已断开");
                // 清理资源
            }
        }
    }
    
    public ConnectionState getCurrentState() {
        return currentState;
    }
}

二、核心API增强

2.1 Stream API改进

JDK 17进一步增强了Stream API,提供了更多实用的操作方法。

新的Stream操作

java 复制代码
import java.util.stream.*;
import java.util.function.*;

/**
 * Stream API增强示例
 */
public class StreamEnhancementsDemo {
    
    /**
     * mapMulti操作 - 一对多映射
     */
    public void demonstrateMapMulti() {
        List<String> words = List.of("hello", "world", "java", "stream");
        
        // 将每个单词拆分成字符
        List<Character> chars = words.stream()
            .mapMulti((String word, Consumer<Character> consumer) -> {
                for (char c : word.toCharArray()) {
                    consumer.accept(c);
                }
            })
            .collect(Collectors.toList());
        
        System.out.println("所有字符: " + chars);
        
        // 处理数字范围
        List<Integer> numbers = List.of(1, 2, 3);
        List<Integer> expanded = numbers.stream()
            .mapMulti((Integer n, Consumer<Integer> consumer) -> {
                for (int i = 1; i <= n; i++) {
                    consumer.accept(i);
                }
            })
            .collect(Collectors.toList());
        
        System.out.println("展开的数字: " + expanded);
    }
    
    /**
     * 复杂的数据处理示例
     */
    public void complexDataProcessing() {
        // 模拟订单数据
        List<Order> orders = List.of(
            new Order("O001", "用户A", List.of(
                new OrderItem("商品1", 2, 100.0),
                new OrderItem("商品2", 1, 50.0)
            )),
            new Order("O002", "用户B", List.of(
                new OrderItem("商品1", 1, 100.0),
                new OrderItem("商品3", 3, 75.0)
            )),
            new Order("O003", "用户A", List.of(
                new OrderItem("商品2", 2, 50.0)
            ))
        );
        
        // 使用mapMulti展开所有订单项
        Map<String, Double> productSales = orders.stream()
            .mapMulti((Order order, Consumer<OrderItem> consumer) -> {
                order.getItems().forEach(consumer);
            })
            .collect(Collectors.groupingBy(
                OrderItem::getProductName,
                Collectors.summingDouble(item -> item.getQuantity() * item.getPrice())
            ));
        
        System.out.println("产品销售统计:");
        productSales.forEach((product, sales) -> 
            System.out.printf("%s: ¥%.2f\n", product, sales));
        
        // 用户购买力分析
        Map<String, OrderSummary> customerSummary = orders.stream()
            .collect(Collectors.groupingBy(
                Order::getCustomerName,
                Collectors.collectingAndThen(
                    Collectors.toList(),
                    orderList -> {
                        int totalOrders = orderList.size();
                        double totalAmount = orderList.stream()
                            .mapToDouble(Order::getTotalAmount)
                            .sum();
                        int totalItems = orderList.stream()
                            .mapToInt(order -> order.getItems().size())
                            .sum();
                        
                        return new OrderSummary(totalOrders, totalAmount, totalItems);
                    }
                )
            ));
        
        System.out.println("\n客户购买统计:");
        customerSummary.forEach((customer, summary) -> 
            System.out.printf("%s: %d笔订单, 总金额¥%.2f, 平均订单¥%.2f\n", 
                customer, summary.orderCount(), summary.totalAmount(), 
                summary.totalAmount() / summary.orderCount()));
    }
    
    /**
     * 并行Stream性能优化
     */
    public void parallelStreamOptimization() {
        // 大数据集处理
        List<Integer> largeDataset = IntStream.range(1, 1_000_000)
            .boxed()
            .collect(Collectors.toList());
        
        // 顺序处理
        long startTime = System.nanoTime();
        double sequentialSum = largeDataset.stream()
            .filter(n -> n % 2 == 0)
            .mapToDouble(n -> Math.sqrt(n))
            .sum();
        long sequentialTime = System.nanoTime() - startTime;
        
        // 并行处理
        startTime = System.nanoTime();
        double parallelSum = largeDataset.parallelStream()
            .filter(n -> n % 2 == 0)
            .mapToDouble(n -> Math.sqrt(n))
            .sum();
        long parallelTime = System.nanoTime() - startTime;
        
        System.out.printf("顺序处理: %.2f, 耗时: %.2f ms\n", 
            sequentialSum, sequentialTime / 1_000_000.0);
        System.out.printf("并行处理: %.2f, 耗时: %.2f ms\n", 
            parallelSum, parallelTime / 1_000_000.0);
        System.out.printf("性能提升: %.2fx\n", 
            (double) sequentialTime / parallelTime);
    }
    
    /**
     * 自定义Collector示例
     */
    public void customCollectorDemo() {
        List<String> words = List.of("apple", "banana", "cherry", "date", "elderberry");
        
        // 自定义收集器:收集到指定分隔符的字符串
        Collector<String, ?, String> joinWithIndex = Collector.of(
            StringBuilder::new,  // supplier
            (sb, str) -> {       // accumulator
                if (sb.length() > 0) sb.append(", ");
                sb.append(String.format("%d:%s", sb.toString().split(", ").length, str));
            },
            (sb1, sb2) -> {      // combiner
                if (sb1.length() > 0 && sb2.length() > 0) sb1.append(", ");
                return sb1.append(sb2);
            },
            StringBuilder::toString  // finisher
        );
        
        String indexedWords = words.stream()
            .collect(joinWithIndex);
        
        System.out.println("带索引的单词: " + indexedWords);
        
        // 统计收集器
        Collector<String, ?, WordStatistics> wordStatsCollector = Collector.of(
            WordStatistics::new,
            (stats, word) -> {
                stats.count++;
                stats.totalLength += word.length();
                stats.longestWord = word.length() > stats.longestWord.length() ? 
                    word : stats.longestWord;
                stats.shortestWord = word.length() < stats.shortestWord.length() ? 
                    word : stats.shortestWord;
            },
            (stats1, stats2) -> {
                WordStatistics merged = new WordStatistics();
                merged.count = stats1.count + stats2.count;
                merged.totalLength = stats1.totalLength + stats2.totalLength;
                merged.longestWord = stats1.longestWord.length() > stats2.longestWord.length() ?
                    stats1.longestWord : stats2.longestWord;
                merged.shortestWord = stats1.shortestWord.length() < stats2.shortestWord.length() ?
                    stats1.shortestWord : stats2.shortestWord;
                return merged;
            }
        );
        
        WordStatistics stats = words.stream()
            .collect(wordStatsCollector);
        
        System.out.println("单词统计: " + stats);
    }
    
    // 数据模型类
    public record Order(String orderId, String customerName, List<OrderItem> items) {
        public double getTotalAmount() {
            return items.stream()
                .mapToDouble(item -> item.getQuantity() * item.getPrice())
                .sum();
        }
    }
    
    public record OrderItem(String productName, int quantity, double price) {}
    
    public record OrderSummary(int orderCount, double totalAmount, int totalItems) {}
    
    public static class WordStatistics {
        int count = 0;
        int totalLength = 0;
        String longestWord = "";
        String shortestWord = "很长很长的初始单词";
        
        @Override
        public String toString() {
            return String.format("WordStatistics{count=%d, avgLength=%.1f, longest='%s', shortest='%s'}", 
                count, (double) totalLength / count, longestWord, shortestWord);
        }
    }
}

2.2 Optional增强

Optional类在JDK 17中获得了新的方法,使其更加强大和易用。

Optional的高级用法

java 复制代码
/**
 * Optional增强功能示例
 */
public class OptionalEnhancementsDemo {
    
    /**
     * Optional.stream()方法的使用
     */
    public void demonstrateOptionalStream() {
        List<Optional<String>> optionalList = List.of(
            Optional.of("apple"),
            Optional.empty(),
            Optional.of("banana"),
            Optional.empty(),
            Optional.of("cherry")
        );
        
        // 使用stream()方法过滤和处理
        List<String> validValues = optionalList.stream()
            .flatMap(Optional::stream)  // 将Optional转换为Stream
            .map(String::toUpperCase)
            .collect(Collectors.toList());
        
        System.out.println("有效值: " + validValues);
        
        // 处理嵌套Optional
        Optional<Optional<String>> nestedOptional = Optional.of(Optional.of("nested value"));
        String result = nestedOptional
            .flatMap(Function.identity())  // 展开嵌套
            .orElse("default");
        
        System.out.println("嵌套Optional结果: " + result);
    }
    
    /**
     * Optional的链式操作
     */
    public void chainedOptionalOperations() {
        User user = new User("张三", "zhang.san@example.com", 
            new Address("北京市", "朝阳区", "12345"));
        
        // 复杂的Optional链式操作
        String cityInfo = Optional.ofNullable(user)
            .map(User::getAddress)
            .filter(addr -> addr.getPostalCode() != null)
            .filter(addr -> addr.getPostalCode().length() == 5)
            .map(addr -> String.format("%s, %s (%s)", 
                addr.getCity(), addr.getDistrict(), addr.getPostalCode()))
            .orElse("地址信息不完整");
        
        System.out.println("城市信息: " + cityInfo);
        
        // 使用Optional处理可能的空值链
        Optional<String> emailDomain = Optional.ofNullable(user)
            .map(User::getEmail)
            .filter(email -> email.contains("@"))
            .map(email -> email.substring(email.indexOf("@") + 1));
        
        emailDomain.ifPresentOrElse(
            domain -> System.out.println("邮箱域名: " + domain),
            () -> System.out.println("无效的邮箱地址")
        );
    }
    
    /**
     * Optional的高级模式
     */
    public void advancedOptionalPatterns() {
        // 配置系统示例
        ConfigurationManager config = new ConfigurationManager();
        
        // 获取配置值的多层回退
        String serverUrl = config.getProperty("server.url")
            .or(() -> config.getProperty("fallback.server.url"))
            .or(() -> config.getEnvironmentVariable("SERVER_URL"))
            .orElse("http://localhost:8080");
        
        System.out.println("服务器URL: " + serverUrl);
        
        // 条件处理
        config.getProperty("debug.enabled")
            .filter("true"::equals)
            .ifPresent(value -> {
                System.out.println("调试模式已启用");
                // 启用调试功能
            });
        
        // 组合多个Optional值
        Optional<String> host = config.getProperty("server.host");
        Optional<String> port = config.getProperty("server.port");
        
        Optional<String> serverAddress = host.flatMap(h -> 
            port.map(p -> h + ":" + p));
        
        serverAddress.ifPresentOrElse(
            addr -> System.out.println("服务器地址: " + addr),
            () -> System.out.println("服务器地址配置不完整")
        );
    }
    
    /**
     * Optional在业务逻辑中的应用
     */
    public void businessLogicWithOptional() {
        UserService userService = new UserService();
        OrderService orderService = new OrderService();
        
        String userId = "user123";
        
        // 复杂的业务流程处理
        Optional<OrderSummary> orderSummary = userService.findUser(userId)
            .filter(user -> user.isActive())
            .flatMap(user -> orderService.getLastOrder(user.getId()))
            .filter(order -> order.getStatus() == OrderStatus.COMPLETED)
            .map(order -> new OrderSummary(
                order.getId(),
                order.getTotalAmount(),
                order.getOrderDate()
            ));
        
        // 处理结果
        String message = orderSummary
            .map(summary -> String.format(
                "最近订单: %s, 金额: ¥%.2f, 日期: %s",
                summary.orderId(),
                summary.amount(),
                summary.date().toString()
            ))
            .orElse("用户无有效订单");
        
        System.out.println(message);
        
        // 错误处理和日志记录
        userService.findUser(userId)
            .ifPresentOrElse(
                user -> System.out.println("找到用户: " + user.getName()),
                () -> {
                    System.err.println("用户不存在: " + userId);
                    // 记录审计日志
                    auditLog("USER_NOT_FOUND", userId);
                }
            );
    }
    
    /**
     * Optional的性能考虑
     */
    public void optionalPerformanceConsiderations() {
        List<String> data = IntStream.range(1, 1000)
            .mapToObj(i -> "item" + i)
            .collect(Collectors.toList());
        
        // 高效的Optional使用
        long startTime = System.nanoTime();
        
        Optional<String> result = data.stream()
            .filter(item -> item.contains("999"))
            .findFirst();
        
        long endTime = System.nanoTime();
        
        System.out.printf("查找耗时: %.2f ms\n", (endTime - startTime) / 1_000_000.0);
        
        result.ifPresentOrElse(
            item -> System.out.println("找到项目: " + item),
            () -> System.out.println("未找到匹配项目")
        );
        
        // 避免不必要的Optional创建
        String value = getValue();
        if (value != null && !value.isEmpty()) {
            processValue(value);
        }
        // 而不是
        // Optional.ofNullable(getValue())
        //     .filter(v -> !v.isEmpty())
        //     .ifPresent(this::processValue);
    }
    
    // 辅助方法和类
    private void auditLog(String action, String details) {
        System.out.println("AUDIT: " + action + " - " + details);
    }
    
    private String getValue() {
        return "some value";
    }
    
    private void processValue(String value) {
        System.out.println("处理值: " + value);
    }
    
    // 数据模型
    public record User(String name, String email, Address address) {
        public String getId() { return name; }
        public boolean isActive() { return true; }
    }
    
    public record Address(String city, String district, String postalCode) {}
    
    public record OrderSummary(String orderId, double amount, LocalDate date) {}
    
    public enum OrderStatus { PENDING, COMPLETED, CANCELLED }
    
    public static class Order {
        private String id;
        private double totalAmount;
        private LocalDate orderDate;
        private OrderStatus status;
        
        // 构造函数和getter方法省略
        public String getId() { return id; }
        public double getTotalAmount() { return totalAmount; }
        public LocalDate getOrderDate() { return orderDate; }
        public OrderStatus getStatus() { return status; }
    }
    
    public static class ConfigurationManager {
        private final Map<String, String> properties = Map.of(
            "server.host", "localhost",
            "debug.enabled", "true"
        );
        
        public Optional<String> getProperty(String key) {
            return Optional.ofNullable(properties.get(key));
        }
        
        public Optional<String> getEnvironmentVariable(String name) {
            return Optional.ofNullable(System.getenv(name));
        }
    }
    
    public static class UserService {
        public Optional<User> findUser(String userId) {
            // 模拟数据库查询
            if ("user123".equals(userId)) {
                return Optional.of(new User("张三", "zhang@example.com", 
                    new Address("北京", "朝阳区", "12345")));
            }
            return Optional.empty();
        }
    }
    
    public static class OrderService {
        public Optional<Order> getLastOrder(String userId) {
            // 模拟订单查询
            return Optional.of(new Order());
        }
    }
}

三、HTTP客户端API深度应用

3.1 现代化HTTP客户端

JDK 17的HTTP客户端API提供了强大而灵活的HTTP通信能力。

高级HTTP客户端使用

java 复制代码
import java.net.http.*;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.Duration;

/**
 * HTTP客户端API深度应用
 */
public class AdvancedHttpClientDemo {
    
    private final HttpClient httpClient;
    
    public AdvancedHttpClientDemo() {
        this.httpClient = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)  // 使用HTTP/2
            .connectTimeout(Duration.ofSeconds(10))
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build();
    }
    
    /**
     * 基本HTTP操作
     */
    public void basicHttpOperations() throws Exception {
        // GET请求
        HttpRequest getRequest = HttpRequest.newBuilder()
            .uri(URI.create("https://api.github.com/users/octocat"))
            .header("Accept", "application/json")
            .header("User-Agent", "Java-HttpClient/17")
            .timeout(Duration.ofSeconds(30))
            .GET()
            .build();
        
        HttpResponse<String> getResponse = httpClient.send(
            getRequest, BodyHandlers.ofString());
        
        System.out.println("GET响应状态: " + getResponse.statusCode());
        System.out.println("响应头: " + getResponse.headers().map());
        System.out.println("响应体: " + getResponse.body());
        
        // POST请求
        String jsonData = """
            {
                "name": "测试用户",
                "email": "test@example.com",
                "age": 25
            }
            """;
        
        HttpRequest postRequest = HttpRequest.newBuilder()
            .uri(URI.create("https://httpbin.org/post"))
            .header("Content-Type", "application/json")
            .header("Accept", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(jsonData))
            .build();
        
        HttpResponse<String> postResponse = httpClient.send(
            postRequest, BodyHandlers.ofString());
        
        System.out.println("POST响应: " + postResponse.body());
    }
    
    /**
     * 异步HTTP请求
     */
    public void asyncHttpRequests() {
        List<String> urls = List.of(
            "https://httpbin.org/delay/1",
            "https://httpbin.org/delay/2",
            "https://httpbin.org/delay/3"
        );
        
        // 并发发送多个请求
        List<CompletableFuture<HttpResponse<String>>> futures = urls.stream()
            .map(url -> HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Accept", "application/json")
                .build())
            .map(request -> httpClient.sendAsync(request, BodyHandlers.ofString()))
            .collect(Collectors.toList());
        
        // 等待所有请求完成
        CompletableFuture<Void> allRequests = CompletableFuture.allOf(
            futures.toArray(new CompletableFuture[0]));
        
        allRequests.thenRun(() -> {
            System.out.println("所有请求完成:");
            futures.forEach(future -> {
                try {
                    HttpResponse<String> response = future.get();
                    System.out.printf("URL: %s, 状态: %d\n", 
                        response.request().uri(), response.statusCode());
                } catch (Exception e) {
                    System.err.println("请求失败: " + e.getMessage());
                }
            });
        }).join();
    }
    
    /**
     * 流式处理和大文件下载
     */
    public void streamingAndFileDownload() throws Exception {
        String downloadUrl = "https://httpbin.org/stream/1000";
        
        // 流式处理响应
        HttpRequest streamRequest = HttpRequest.newBuilder()
            .uri(URI.create(downloadUrl))
            .build();
        
        HttpResponse<Stream<String>> streamResponse = httpClient.send(
            streamRequest, 
            BodyHandlers.ofLines()
        );
        
        System.out.println("处理流式响应:");
        streamResponse.body()
            .limit(10)  // 只处理前10行
            .forEach(line -> System.out.println("行: " + line));
        
        // 文件下载
        Path downloadPath = Paths.get("downloaded_file.json");
        HttpRequest downloadRequest = HttpRequest.newBuilder()
            .uri(URI.create("https://httpbin.org/json"))
            .build();
        
        HttpResponse<Path> fileResponse = httpClient.send(
            downloadRequest, 
            BodyHandlers.ofFile(downloadPath)
        );
        
        System.out.println("文件下载完成: " + fileResponse.body());
        System.out.println("文件大小: " + Files.size(downloadPath) + " bytes");
        
        // 清理下载的文件
        Files.deleteIfExists(downloadPath);
    }
    
    /**
     * 错误处理和重试机制
     */
    public void errorHandlingAndRetry() {
        String unreliableUrl = "https://httpbin.org/status/500";
        
        RetryableHttpClient retryClient = new RetryableHttpClient(httpClient);
        
        try {
            HttpResponse<String> response = retryClient.sendWithRetry(
                HttpRequest.newBuilder()
                    .uri(URI.create(unreliableUrl))
                    .build(),
                BodyHandlers.ofString(),
                3  // 最大重试次数
            );
            
            System.out.println("请求成功: " + response.statusCode());
        } catch (Exception e) {
            System.err.println("请求最终失败: " + e.getMessage());
        }
    }
    
    /**
     * WebSocket客户端示例
     */
    public void webSocketExample() throws Exception {
        WebSocket webSocket = httpClient.newWebSocketBuilder()
            .buildAsync(URI.create("wss://echo.websocket.org"), 
                new WebSocketListener() {
                    @Override
                    public void onOpen(WebSocket webSocket) {
                        System.out.println("WebSocket连接已建立");
                        webSocket.sendText("Hello WebSocket!", true);
                        WebSocket.Listener.super.onOpen(webSocket);
                    }
                    
                    @Override
                    public CompletionStage<?> onText(WebSocket webSocket, 
                                                   CharSequence data, boolean last) {
                        System.out.println("收到消息: " + data);
                        return WebSocket.Listener.super.onText(webSocket, data, last);
                    }
                    
                    @Override
                    public CompletionStage<?> onClose(WebSocket webSocket, 
                                                    int statusCode, String reason) {
                        System.out.println("WebSocket连接关闭: " + reason);
                        return WebSocket.Listener.super.onClose(webSocket, statusCode, reason);
                    }
                    
                    @Override
                    public void onError(WebSocket webSocket, Throwable error) {
                        System.err.println("WebSocket错误: " + error.getMessage());
                        WebSocket.Listener.super.onError(webSocket, error);
                    }
                })
            .get();
        
        // 发送几条消息
        webSocket.sendText("消息1", true);
        webSocket.sendText("消息2", true);
        webSocket.sendText("消息3", true);
        
        // 等待一段时间后关闭连接
        Thread.sleep(5000);
        webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "正常关闭");
    }
    
    /**
     * 自定义请求拦截器
     */
    public static class InterceptingHttpClient {
        private final HttpClient delegate;
        private final List<RequestInterceptor> interceptors;
        
        public InterceptingHttpClient(HttpClient delegate) {
            this.delegate = delegate;
            this.interceptors = new ArrayList<>();
        }
        
        public void addInterceptor(RequestInterceptor interceptor) {
            interceptors.add(interceptor);
        }
        
        public <T> HttpResponse<T> send(HttpRequest request, 
                                      HttpResponse.BodyHandler<T> responseBodyHandler) 
                throws IOException, InterruptedException {
            
            // 应用请求拦截器
            HttpRequest modifiedRequest = request;
            for (RequestInterceptor interceptor : interceptors) {
                modifiedRequest = interceptor.intercept(modifiedRequest);
            }
            
            long startTime = System.nanoTime();
            HttpResponse<T> response = delegate.send(modifiedRequest, responseBodyHandler);
            long endTime = System.nanoTime();
            
            // 记录请求信息
            System.out.printf("HTTP %s %s -> %d (%.2f ms)\n",
                modifiedRequest.method(),
                modifiedRequest.uri(),
                response.statusCode(),
                (endTime - startTime) / 1_000_000.0
            );
            
            return response;
        }
        
        @FunctionalInterface
        public interface RequestInterceptor {
            HttpRequest intercept(HttpRequest request);
        }
    }
    
    /**
     * 可重试的HTTP客户端
     */
    public static class RetryableHttpClient {
        private final HttpClient httpClient;
        
        public RetryableHttpClient(HttpClient httpClient) {
            this.httpClient = httpClient;
        }
        
        public <T> HttpResponse<T> sendWithRetry(HttpRequest request, 
                                               HttpResponse.BodyHandler<T> bodyHandler,
                                               int maxRetries) 
                throws IOException, InterruptedException {
            
            Exception lastException = null;
            
            for (int attempt = 0; attempt <= maxRetries; attempt++) {
                try {
                    HttpResponse<T> response = httpClient.send(request, bodyHandler);
                    
                    // 如果是5xx错误,进行重试
                    if (response.statusCode() >= 500 && attempt < maxRetries) {
                        System.out.printf("服务器错误 %d,第 %d 次重试...\n", 
                            response.statusCode(), attempt + 1);
                        Thread.sleep(1000 * (attempt + 1)); // 指数退避
                        continue;
                    }
                    
                    return response;
                    
                } catch (Exception e) {
                    lastException = e;
                    if (attempt < maxRetries) {
                        System.out.printf("请求异常,第 %d 次重试: %s\n", 
                            attempt + 1, e.getMessage());
                        Thread.sleep(1000 * (attempt + 1));
                    }
                }
            }
            
            throw new IOException("请求失败,已重试 " + maxRetries + " 次", lastException);
        }
    }
    
    /**
     * HTTP客户端工厂
     */
    public static class HttpClientFactory {
        
        public static HttpClient createDefault() {
            return HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .connectTimeout(Duration.ofSeconds(10))
                .build();
        }
        
        public static HttpClient createSecure() {
            return HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .connectTimeout(Duration.ofSeconds(10))
                .followRedirects(HttpClient.Redirect.NEVER)
                .sslContext(createSecureSSLContext())
                .build();
        }
        
        public static HttpClient createWithProxy(String proxyHost, int proxyPort) {
            return HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .connectTimeout(Duration.ofSeconds(10))
                .proxy(ProxySelector.of(new InetSocketAddress(proxyHost, proxyPort)))
                .build();
        }
        
        private static SSLContext createSecureSSLContext() {
            try {
                SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
                sslContext.init(null, null, new SecureRandom());
                return sslContext;
            } catch (Exception e) {
                throw new RuntimeException("创建SSL上下文失败", e);
            }
        }
    }
}

3.2 文本处理增强

文本块和字符串处理改进

java 复制代码
/**
 * 文本处理增强功能示例
 */
public class TextProcessingEnhancements {
    
    /**
     * 文本块(Text Blocks)的高级用法
     */
    public void textBlockAdvancedUsage() {
        // SQL查询文本块
        String sqlQuery = """
            SELECT u.id, u.name, u.email, p.title, p.content
            FROM users u
            INNER JOIN posts p ON u.id = p.user_id
            WHERE u.active = true
              AND p.published_date >= ?
              AND p.category IN ('tech', 'science')
            ORDER BY p.published_date DESC
            LIMIT 10
            """;
        
        System.out.println("SQL查询:");
        System.out.println(sqlQuery);
        
        // JSON模板
        String jsonTemplate = """
            {
                "user": {
                    "id": "%s",
                    "name": "%s",
                    "email": "%s",
                    "preferences": {
                        "theme": "dark",
                        "notifications": true,
                        "language": "zh-CN"
                    }
                },
                "metadata": {
                    "version": "1.0",
                    "timestamp": "%s"
                }
            }
            """;
        
        String userId = "12345";
        String userName = "张三";
        String userEmail = "zhangsan@example.com";
        String timestamp = Instant.now().toString();
        
        String formattedJson = String.format(jsonTemplate, 
            userId, userName, userEmail, timestamp);
        
        System.out.println("格式化的JSON:");
        System.out.println(formattedJson);
        
        // HTML模板
        String htmlTemplate = """
            <!DOCTYPE html>
            <html lang="zh-CN">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>%s</title>
                <style>
                    body {
                        font-family: 'Microsoft YaHei', sans-serif;
                        margin: 0;
                        padding: 20px;
                        background-color: #f5f5f5;
                    }
                    .container {
                        max-width: 800px;
                        margin: 0 auto;
                        background: white;
                        padding: 30px;
                        border-radius: 8px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                    }
                    h1 {
                        color: #333;
                        border-bottom: 2px solid #007acc;
                        padding-bottom: 10px;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <h1>%s</h1>
                    <p>%s</p>
                    <p><strong>生成时间:</strong> %s</p>
                </div>
            </body>
            </html>
            """;
        
        String pageTitle = "JDK 17 示例页面";
        String content = "这是使用文本块生成的HTML页面示例。";
        String generatedHtml = String.format(htmlTemplate, 
            pageTitle, pageTitle, content, 
            LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        
        System.out.println("生成的HTML:");
        System.out.println(generatedHtml);
    }
    
    /**
     * 字符串处理的新方法
     */
    public void stringProcessingMethods() {
        String text = "  Hello, World! This is a test string.  ";
        
        // 字符串去除前后空白
        String trimmed = text.strip();
        System.out.println("去除空白: '" + trimmed + "'");
        
        // 去除前导空白
        String leadingTrimmed = text.stripLeading();
        System.out.println("去除前导空白: '" + leadingTrimmed + "'");
        
        // 去除尾随空白
        String trailingTrimmed = text.stripTrailing();
        System.out.println("去除尾随空白: '" + trailingTrimmed + "'");
        
        // 检查字符串是否为空白
        System.out.println("是否为空白: " + "   ".isBlank());
        System.out.println("是否为空白: " + "text".isBlank());
        
        // 重复字符串
        String repeated = "Java ".repeat(3);
        System.out.println("重复字符串: " + repeated);
        
        // 按行分割
        String multilineText = """
            第一行
            第二行
            第三行
            """;
        
        List<String> lines = multilineText.lines()
            .collect(Collectors.toList());
        
        System.out.println("分割行数: " + lines.size());
        lines.forEach(line -> System.out.println("行: '" + line + "'"));
        
        // 缩进处理
        String code = """
            public class Example {
                public void method() {
                    System.out.println("Hello");
                }
            }
            """;
        
        String indentedCode = code.indent(4);
        System.out.println("增加缩进:");
        System.out.println(indentedCode);
        
        String dedentedCode = indentedCode.indent(-2);
        System.out.println("减少缩进:");
        System.out.println(dedentedCode);
    }
}

四、开发工具升级与集成

4.1 性能优化和监控工具

JDK 17提供了更强大的性能分析和监控工具,帮助开发者构建高性能应用。

应用性能监控(APM)集成

java 复制代码
/**
 * 应用性能监控集成示例
 */
public class ApplicationPerformanceMonitoring {
    
    /**
     * 性能指标收集器
     */
    public class PerformanceCollector {
        
        private final Map<String, MetricSummary> metrics = new ConcurrentHashMap<>();
        private final ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(2);
        
        public PerformanceCollector() {
            // 定期输出性能报告
            scheduler.scheduleAtFixedRate(this::reportMetrics, 60, 60, TimeUnit.SECONDS);
        }
        
        /**
         * 记录操作耗时
         */
        public void recordOperationTime(String operation, long durationNanos) {
            metrics.compute(operation, (key, existing) -> {
                if (existing == null) {
                    return new MetricSummary(1, durationNanos, durationNanos, durationNanos);
                } else {
                    return new MetricSummary(
                        existing.count() + 1,
                        existing.totalTime() + durationNanos,
                        Math.min(existing.minTime(), durationNanos),
                        Math.max(existing.maxTime(), durationNanos)
                    );
                }
            });
        }
        
        /**
         * 自动计时装饰器
         */
        public <T> T timeOperation(String operationName, Supplier<T> operation) {
            long startTime = System.nanoTime();
            try {
                return operation.get();
            } finally {
                long endTime = System.nanoTime();
                recordOperationTime(operationName, endTime - startTime);
            }
        }
        
        /**
         * 异步操作计时
         */
        public <T> CompletableFuture<T> timeAsyncOperation(String operationName, 
                                                         Supplier<CompletableFuture<T>> operation) {
            long startTime = System.nanoTime();
            return operation.get()
                .whenComplete((result, throwable) -> {
                    long endTime = System.nanoTime();
                    recordOperationTime(operationName, endTime - startTime);
                });
        }
        
        /**
         * 生成性能报告
         */
        private void reportMetrics() {
            if (metrics.isEmpty()) return;
            
            System.out.println("\n=== 性能指标报告 ===");
            metrics.entrySet().stream()
                .sorted(Map.Entry.<String, MetricSummary>comparingByValue(
                    (m1, m2) -> Long.compare(m2.totalTime(), m1.totalTime())))
                .forEach(entry -> {
                    String operation = entry.getKey();
                    MetricSummary summary = entry.getValue();
                    
                    double avgTimeMs = (summary.totalTime() / (double) summary.count()) / 1_000_000.0;
                    double minTimeMs = summary.minTime() / 1_000_000.0;
                    double maxTimeMs = summary.maxTime() / 1_000_000.0;
                    
                    System.out.printf("%-30s: 调用%4d次, 平均%.2fms, 最快%.2fms, 最慢%.2fms\n",
                        operation, summary.count(), avgTimeMs, minTimeMs, maxTimeMs);
                });
            System.out.println();
        }
        
        public void shutdown() {
            scheduler.shutdown();
        }
    }
    
    /**
     * 内存使用监控
     */
    public class MemoryMonitor {
        
        private final ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(1);
        private final List<MemoryUsagePoint> memoryHistory = new ArrayList<>();
        private final int maxHistorySize = 100;
        
        public MemoryMonitor() {
            // 每10秒收集一次内存使用情况
            scheduler.scheduleAtFixedRate(this::collectMemoryUsage, 0, 10, TimeUnit.SECONDS);
        }
        
        private void collectMemoryUsage() {
            Runtime runtime = Runtime.getRuntime();
            long totalMemory = runtime.totalMemory();
            long freeMemory = runtime.freeMemory();
            long usedMemory = totalMemory - freeMemory;
            long maxMemory = runtime.maxMemory();
            
            MemoryUsagePoint point = new MemoryUsagePoint(
                System.currentTimeMillis(),
                usedMemory,
                totalMemory,
                maxMemory
            );
            
            synchronized (memoryHistory) {
                memoryHistory.add(point);
                if (memoryHistory.size() > maxHistorySize) {
                    memoryHistory.remove(0);
                }
            }
            
            // 检查内存使用警告
            double usagePercentage = (double) usedMemory / maxMemory * 100;
            if (usagePercentage > 80) {
                System.err.printf("⚠️ 内存使用率过高: %.1f%% (%d MB / %d MB)\n",
                    usagePercentage, usedMemory / 1024 / 1024, maxMemory / 1024 / 1024);
            }
        }
        
        /**
         * 生成内存使用趋势报告
         */
        public String generateMemoryTrendReport() {
            synchronized (memoryHistory) {
                if (memoryHistory.isEmpty()) {
                    return "无内存使用数据";
                }
                
                StringBuilder report = new StringBuilder();
                report.append("=== 内存使用趋势 ===\n");
                
                MemoryUsagePoint latest = memoryHistory.get(memoryHistory.size() - 1);
                double currentUsagePercent = (double) latest.usedMemory() / latest.maxMemory() * 100;
                
                report.append(String.format("当前内存使用: %.1f%% (%d MB / %d MB)\n",
                    currentUsagePercent,
                    latest.usedMemory() / 1024 / 1024,
                    latest.maxMemory() / 1024 / 1024));
                
                // 计算内存使用趋势
                if (memoryHistory.size() >= 2) {
                    MemoryUsagePoint first = memoryHistory.get(0);
                    double firstUsagePercent = (double) first.usedMemory() / first.maxMemory() * 100;
                    double trend = currentUsagePercent - firstUsagePercent;
                    
                    report.append(String.format("内存使用趋势: %+.1f%% (过去%d分钟)\n",
                        trend, memoryHistory.size() * 10 / 60));
                }
                
                // 统计信息
                DoubleSummaryStatistics stats = memoryHistory.stream()
                    .mapToDouble(point -> (double) point.usedMemory() / point.maxMemory() * 100)
                    .summaryStatistics();
                
                report.append(String.format("统计信息: 平均%.1f%%, 最低%.1f%%, 最高%.1f%%\n",
                    stats.getAverage(), stats.getMin(), stats.getMax()));
                
                return report.toString();
            }
        }
        
        public void shutdown() {
            scheduler.shutdown();
        }
    }
    
    /**
     * 线程监控器
     */
    public class ThreadMonitor {
        
        private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        private final ScheduledExecutorService scheduler = 
            Executors.newScheduledThreadPool(1);
        
        public ThreadMonitor() {
            // 启用线程CPU时间测量(如果支持)
            if (threadBean.isThreadCpuTimeSupported()) {
                threadBean.setThreadCpuTimeEnabled(true);
            }
            
            // 定期检查线程状态
            scheduler.scheduleAtFixedRate(this::checkThreadHealth, 30, 30, TimeUnit.SECONDS);
        }
        
        private void checkThreadHealth() {
            // 检查死锁
            long[] deadlockedThreads = threadBean.findDeadlockedThreads();
            if (deadlockedThreads != null && deadlockedThreads.length > 0) {
                System.err.println("⚠️ 检测到死锁线程: " + deadlockedThreads.length + " 个");
                
                ThreadInfo[] threadInfos = threadBean.getThreadInfo(deadlockedThreads);
                for (ThreadInfo info : threadInfos) {
                    System.err.printf("  死锁线程: %s (ID: %d)\n", 
                        info.getThreadName(), info.getThreadId());
                }
            }
            
            // 检查线程数量
            int threadCount = threadBean.getThreadCount();
            int peakThreadCount = threadBean.getPeakThreadCount();
            
            if (threadCount > 200) {  // 假设200是警告阈值
                System.err.printf("⚠️ 线程数量过多: 当前%d个, 峰值%d个\n", 
                    threadCount, peakThreadCount);
            }
            
            // 分析线程状态分布
            analyzeThreadStates();
        }
        
        private void analyzeThreadStates() {
            long[] allThreadIds = threadBean.getAllThreadIds();
            ThreadInfo[] threadInfos = threadBean.getThreadInfo(allThreadIds);
            
            Map<Thread.State, Long> stateCount = Arrays.stream(threadInfos)
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(
                    ThreadInfo::getThreadState,
                    Collectors.counting()));
            
            long blockedThreads = stateCount.getOrDefault(Thread.State.BLOCKED, 0L);
            long waitingThreads = stateCount.getOrDefault(Thread.State.WAITING, 0L);
            
            if (blockedThreads > 10) {
                System.err.printf("⚠️ 阻塞线程过多: %d个线程处于BLOCKED状态\n", blockedThreads);
            }
            
            if (waitingThreads > 50) {
                System.err.printf("⚠️ 等待线程过多: %d个线程处于WAITING状态\n", waitingThreads);
            }
        }
        
        /**
         * 获取CPU使用率最高的线程
         */
        public List<ThreadCpuInfo> getTopCpuThreads(int topN) {
            if (!threadBean.isThreadCpuTimeSupported()) {
                return List.of();
            }
            
            long[] allThreadIds = threadBean.getAllThreadIds();
            
            return Arrays.stream(allThreadIds)
                .mapToObj(threadId -> {
                    ThreadInfo info = threadBean.getThreadInfo(threadId);
                    long cpuTime = threadBean.getThreadCpuTime(threadId);
                    
                    if (info != null && cpuTime != -1) {
                        return new ThreadCpuInfo(
                            info.getThreadName(),
                            threadId,
                            cpuTime / 1_000_000, // 转换为毫秒
                            info.getThreadState()
                        );
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .sorted((t1, t2) -> Long.compare(t2.cpuTimeMs(), t1.cpuTimeMs()))
                .limit(topN)
                .collect(Collectors.toList());
        }
        
        public void shutdown() {
            scheduler.shutdown();
        }
    }
    
    /**
     * 集成的APM系统
     */
    public class IntegratedAPM {
        
        private final PerformanceCollector performanceCollector;
        private final MemoryMonitor memoryMonitor;
        private final ThreadMonitor threadMonitor;
        
        public IntegratedAPM() {
            this.performanceCollector = new PerformanceCollector();
            this.memoryMonitor = new MemoryMonitor();
            this.threadMonitor = new ThreadMonitor();
        }
        
        /**
         * 生成综合性能报告
         */
        public String generateComprehensiveReport() {
            StringBuilder report = new StringBuilder();
            report.append("=== 综合性能报告 ===\n\n");
            
            // 内存报告
            report.append(memoryMonitor.generateMemoryTrendReport()).append("\n");
            
            // 线程报告
            report.append("=== 线程状态 ===\n");
            report.append(String.format("当前线程数: %d\n", 
                ManagementFactory.getThreadMXBean().getThreadCount()));
            
            List<ThreadCpuInfo> topCpuThreads = threadMonitor.getTopCpuThreads(5);
            if (!topCpuThreads.isEmpty()) {
                report.append("CPU使用率最高的线程:\n");
                topCpuThreads.forEach(threadInfo -> 
                    report.append(String.format("  %s (ID: %d): %d ms CPU时间, 状态: %s\n",
                        threadInfo.name(), threadInfo.threadId(), 
                        threadInfo.cpuTimeMs(), threadInfo.state())));
            }
            
            return report.toString();
        }
        
        public PerformanceCollector getPerformanceCollector() {
            return performanceCollector;
        }
        
        public void shutdown() {
            performanceCollector.shutdown();
            memoryMonitor.shutdown();
            threadMonitor.shutdown();
        }
    }
    
    // 数据模型
    public record MetricSummary(long count, long totalTime, long minTime, long maxTime) {}
    
    public record MemoryUsagePoint(long timestamp, long usedMemory, 
                                 long totalMemory, long maxMemory) {}
    
    public record ThreadCpuInfo(String name, long threadId, long cpuTimeMs, 
                              Thread.State state) {}
}

五、总结与展望

5.1 JDK 17开发工具与API增强总结

通过第五期的深入探索,我们全面了解了JDK 17在开发工具和API方面的重大提升:

🎯 核心特性亮点

  1. 现代语言特性

    • Pattern Matching简化了复杂的类型检查和转换
    • Sealed Classes提供了更精确的继承控制
    • 增强的Switch表达式让代码更加简洁
  2. 强大的API增强

    • Stream API的mapMulti等新操作提升了数据处理能力
    • Optional的stream()方法增强了函数式编程体验
    • HTTP客户端API提供了现代化的网络通信方案
  3. 开发效率提升

    • 文本块让多行字符串处理更加直观
    • 增强的字符串处理方法提高了文本操作效率
    • 改进的编译器提供了更好的类型推断
  4. 性能监控工具

    • 集成的APM系统提供全面的性能洞察
    • 内存和线程监控帮助优化应用性能
    • 自动化的性能指标收集简化了监控工作

💡 最佳实践建议

java 复制代码
// 1. 充分利用Pattern Matching
public String processData(Object data) {
    return switch (data) {
        case String str when !str.isEmpty() -> "文本: " + str;
        case List<?> list when !list.isEmpty() -> "列表: " + list.size() + " 项";
        case null -> "空值";
        default -> "未知类型";
    };
}

// 2. 使用Sealed Classes设计状态机
public sealed interface ConnectionState 
    permits Connected, Disconnected, Connecting {
    
    default String getDisplayName() {
        return switch (this) {
            case Connected c -> "已连接";
            case Disconnected d -> "已断开";
            case Connecting c -> "连接中";
        };
    }
}

// 3. 发挥HTTP客户端API的优势
HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .followRedirects(HttpClient.Redirect.NORMAL)
    .build();

// 4. 使用文本块提高代码可读性
String htmlTemplate = """
    <div class="user-card">
        <h3>%s</h3>
        <p>Email: %s</p>
    </div>
    """;

5.2 开发体验提升

JDK 17的这些增强功能显著提升了Java开发体验:

  • 类型安全性增强 - Pattern Matching和Sealed Classes提供了更强的编译时保证
  • 代码简洁性提升 - 新的语法特性减少了样板代码
  • 性能监控便利 - 内置的监控工具简化了性能分析工作
  • 现代化API - HTTP客户端等API符合现代开发需求

🚀 第六期预告

下一期我们将聚焦生态系统与实战应用,内容包括:

  • 构建工具集成 - Maven、Gradle与JDK 17的深度集成
  • 框架适配 - Spring、微服务框架的JDK 17优化
  • 容器化部署 - Docker、Kubernetes环境下的最佳实践
  • 云原生应用 - 构建现代化的云原生Java应用
  • 迁移策略 - 从旧版本到JDK 17的平滑迁移方案

JDK 17的开发工具与API增强为Java开发者提供了强大的工具集,让我们能够构建更加现代化、高效的Java应用!

相关推荐
AI风老师19 分钟前
5、docker镜像管理命令
java·docker·eureka
SmalBox25 分钟前
【渲染流水线】[应用阶段]-[定制裁剪]以UnityURP为例
架构
用户849137175471631 分钟前
JustAuth实战系列(第5期):建造者模式进阶 - AuthRequestBuilder设计解析
java·设计模式·架构
励志成为糕手1 小时前
从反射到方法句柄:深入探索Java动态编程的终极解决方案
java·开发语言
是乐谷2 小时前
饿了么招java开发咯
java·开发语言·人工智能·程序人生·面试·职场和发展
zhysunny2 小时前
20.万物皆可变身术:状态模式架构全景解析
java·状态模式
hongjunwu2 小时前
Java集合的遍历方式(全解析)
java·开发语言·windows
cccc来财2 小时前
Golang的本地缓存freecache
java·开发语言·jvm
Barcke2 小时前
缓存界的 "双保险":打工人救星来了!(本地缓存 + Redis 双剑合璧,轻松应对高并发)
java·后端