Skip to content
第 11 / 250 章后端⏱ 10 分钟阅读

第 11 章:可变参数与命令行参数

学习目标

  • 掌握可变参数(varargs)的用法
  • 理解可变参数的底层实现
  • 学会解析 main 方法的命令行参数

一、什么是可变参数?

可变参数允许方法接受任意数量的同类型参数。

java
public static int sum(int... numbers) {  // ① int... 表示可变参数
    int total = 0;
    for (int n : numbers) {
        total += n;
    }
    return total;
}

// 可以传任意个 int
sum(1, 2);              // 3
sum(1, 2, 3, 4, 5);     // 15
sum();                  // 0(零个参数)
sum(new int[]{1, 2});   // 3(传数组也行)

二、可变参数的本质

可变参数底层就是数组

java
// 这两种写法完全等价
public static int sum(int... numbers) { ... }
public static int sum(int[] numbers) { ... }  // 等价

三、可变参数的三条规则

3.1 只能有一个可变参数

java
// ❌ 编译报错
public void test(int... nums, String... strs) { }

// ✅ 合法
public void test(int... nums) { }

3.2 必须放在参数列表最后

java
// ❌ 编译报错
public void test(String... strs, int count) { }

// ✅ 合法
public void test(int count, String... strs) { }

3.3 调用时少传一个数组

java
// ✅ 可以直接传多个值
sum(1, 2, 3, 4, 5);

// ✅ 也可以传数组
sum(new int[]{1, 2, 3});

四、可变参数的典型应用

4.1 字符串拼接

java
public static String concat(String separator, String... parts) {
    return String.join(separator, parts);
}

concat("-", "2024", "08", "12");   // "2024-08-12"
concat("/", "a", "b", "c");        // "a/b/c"

4.2 日志方法

java
public static void log(String format, Object... args) {
    System.out.println(String.format(format, args));
}

log("用户 %s 登录失败,错误码 %d", "张三", 401);
// 输出:用户 张三 登录失败,错误码 401

4.3 断言 / 校验

java
public static void requireNonNull(Object... args) {
    for (int i = 0; i < args.length; i++) {
        if (args[i] == null) {
            throw new IllegalArgumentException("第 " + i + " 个参数为 null");
        }
    }
}

requireNonNull("a", "b", "c", null, "e");  // 抛异常

五、可变参数 vs 数组参数

维度可变参数 int...数组参数 int[]
调用方式sum(1,2,3)sum(new int[]{1,2,3})
空参数sum() 合法必须传数组
重载冲突可能冲突不冲突
java
// ❌ 可变参数和数组不能重载
public void test(int... nums) { }
public void test(int[] nums) { }  // 编译报错:与方法签名相同

六、main 方法的命令行参数

java
public static void main(String[] args) {
    // args 是 String[],接收命令行参数
}
bash
# 运行 java MyApp arg1 arg2 arg3
# args = ["arg1", "arg2", "arg3"]
java
public class ArgsDemo {
    public static void main(String[] args) {
        System.out.println("参数个数: " + args.length);
        for (int i = 0; i < args.length; i++) {
            System.out.println("args[" + i + "] = " + args[i]);
        }
    }
}
bash
$ java ArgsDemo hello world 123
参数个数: 3
args[0] = hello
args[1] = world
args[2] = 123

IDEA 配置参数:Run → Edit Configurations → Program arguments

七、完整代码示例

java
/**
 * 可变参数与命令行参数示例
 *
 * 配套文档:第 11 章 可变参数与命令行参数
 * 运行方式:java VarargsDemo a b c
 */
public class VarargsDemo {

    // 可变参数求和
    public static int sum(int... numbers) {
        int total = 0;
        for (int n : numbers) {
            total += n;
        }
        return total;
    }

    // 字符串拼接
    public static String join(String separator, String... parts) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < parts.length; i++) {
            if (i > 0) sb.append(separator);
            sb.append(parts[i]);
        }
        return sb.toString();
    }

    // 格式化日志
    public static void log(String format, Object... args) {
        System.out.println("[LOG] " + String.format(format, args));
    }

    // 校验非空
    public static void checkNotNull(Object... args) {
        for (int i = 0; i < args.length; i++) {
            if (args[i] == null) {
                throw new IllegalArgumentException(
                    "第 " + i + " 个参数不能为 null"
                );
            }
        }
    }

    public static void main(String[] args) {
        // 1. 可变参数
        System.out.println("=== 可变参数求和 ===");
        System.out.println("sum(1, 2) = " + sum(1, 2));
        System.out.println("sum(1, 2, 3, 4, 5) = " + sum(1, 2, 3, 4, 5));
        System.out.println("sum() = " + sum());

        // 2. 字符串拼接
        System.out.println("\n=== 字符串拼接 ===");
        System.out.println(join("-", "2024", "08", "12"));
        System.out.println(join("/", "a", "b", "c"));

        // 3. 格式化日志
        System.out.println("\n=== 格式化日志 ===");
        log("用户 %s 登录 %s", "张三", "成功");
        log("订单 %d 状态: %s", 12345, "已支付");

        // 4. 命令行参数
        System.out.println("\n=== 命令行参数 ===");
        System.out.println("参数个数: " + args.length);
        for (int i = 0; i < args.length; i++) {
            System.out.println("args[" + i + "] = " + args[i]);
        }
    }
}

八、本章小结

要点关键
可变参数语法类型... 名字
本质编译为数组
规则只有一个、必须在最后、可传数组
main 参数String[] args 接收命令行参数
典型应用求和、字符串拼接、格式化日志

动手练习

练习 1:基础题

写一个 max 方法的可变参数版本:

java
public static int max(int... numbers)
// max(1, 5, 3, 9, 2) = 9
// max() = Integer.MIN_VALUE(或者抛异常)

练习 2:进阶题

写一个工具方法,判断所有参数是否都满足某个条件:

java
public static boolean allMatch(int[] arr, IntPredicate predicate)
// 用可变参数重构
public static boolean allMatch(IntPredicate predicate, int... nums)

练习 3:挑战题

写一个命令行计算器:

bash
$ java Calc add 3 5
# 输出:8

$ java Calc sub 10 3
# 输出:7

$ java Calc mul 4 5
# 输出:20

$ java Calc div 10 2
# 输出:5

下一章第 12 章:数组

本站基于 VitePress 构建 · 由 Codebook 团队维护