Java 可变参数机制

基本语法和使用

1. 基本语法

public class VarargsExample {
    // 可变参数声明:类型... 参数名
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {total += num;}
        return total;
    }
    // 可变参数必须放在最后
    public static void printInfo(String message, int... values) {
        System.out.print(message + ": ");
        for (int val : values) {System.out.print(val + " ");}
        System.out.println();
    }
    public static void main(String[] args) {
        // 多种调用方式
        System.out.println(sum(1, 2, 3));        // 6
        System.out.println(sum(1, 2, 3, 4, 5)); // 15
        System.out.println(sum());               // 0 - 空参数
        System.out.println(sum(10));             // 10 - 单个参数
        // 也可以传递数组
        int[] arr = {1, 2, 3};
        System.out.println(sum(arr));            // 6
        printInfo("数值", 1, 2, 3, 4);
    }
}

2. 编译器的处理

// 编译前
public void method(String... args)
// 编译后等价于
public void method(String[] args)

实际应用场景分析

  1. 工具类和辅助方法 - 提供简洁的API

  2. 日志和格式化 - 参数数量变化大

  3. 测试代码 - 可读性和便利性更重要

  4. 配置和构建器 - 灵活的调用方式

现代Java的改进

1. 结合Stream API

public class ModernVarargs {
    
    // 可变参数 + Stream = 强大组合
    @SafeVarargs
    public static <T> List<T> mergeLists(List<T>... lists) {
        return Arrays.stream(lists)
                    .flatMap(List::stream)
                    .collect(Collectors.toList());
    }
    
    // 处理null安全的可变参数
    public static <T> void printValues(T... values) {
        Arrays.stream(values)
              .filter(Objects::nonNull)
              .forEach(System.out::println);
    }
}

// 使用记录类(Java 16+)
record Point(int x, int y) {
    // 可变参数构造器
    public static Point of(int... coordinates) {
        return coordinates.length >= 2 ? 
            new Point(coordinates[0], coordinates[1]) : 
            new Point(0, 0);
    }
}

2. 与容器API的互操作

可以使用传容器传参的方式代替

public class Interoperability {
    
    // 最佳实践:同时提供两种版本
    public static class ApiDesign {
        // 可变参数版本 - 方便调用
        public static void execute(Runnable... tasks) {
            execute(Arrays.asList(tasks));
        }
        
        // 容器版本 - 性能更好
        public static void execute(List<Runnable> tasks) {
            tasks.forEach(Runnable::run);
        }
    }
    
    public static void demo() {
        // 根据情况选择合适的方法
        Runnable task1 = () -> System.out.println("Task 1");
        Runnable task2 = () -> System.out.println("Task 2");
        
        // 少量固定任务 - 使用可变参数
        ApiDesign.execute(task1, task2);
        
        // 动态生成的任务列表 - 使用容器
        List<Runnable> dynamicTasks = generateTasks();
        ApiDesign.execute(dynamicTasks);
    }
}

性能考虑

可变参数会创建数组,在热点代码中可能有影响
每次调用都会创建新数组

对于性能敏感的场景,考虑重载方法
 
 
 
posted @ 2025-11-16 16:56  YukiRinLL  阅读(0)  评论(0)    收藏  举报