Java 可变参数 Object... args 详解:原理、用法与实战场景

文章目录

  • [一、什么是 Object... args?](#一、什么是 Object... args?)
  • [二、Object... args 的本质是什么?](#二、Object... args 的本质是什么?)
  • [三、Object... args 的基本用法](#三、Object... args 的基本用法)
  • [四、Object... args 在方法内部如何使用?](#四、Object... args 在方法内部如何使用?)
  • [五、Object... args 的语法规则](#五、Object... args 的语法规则)
  • [六、真实业务场景:Spring Boot + Redis Lua](#六、真实业务场景:Spring Boot + Redis Lua)
  • [七、Object... args 与 Object[] 的对比](#七、Object... args 与 Object[] 的对比)
  • 八、常见误区与坑点
  • 九、总结

在 Java 开发过程中,你几乎不可避免地会看到下面这样的代码:

java 复制代码
public Long execute(LuaScriptEnum scriptEnum,
                    List<String> keys,
                    Object... args)

第一次看到 Object... args,很多人都会感到困惑:

  • 方法明明定义了 3 个参数,为什么调用时只传 2 个也不报错?
  • Object... args 到底是不是必须要传?
  • 它和 Object[] 有什么区别?
  • 为什么 Spring、RedisTemplate、JUnit、日志框架中大量使用这种写法?

事实上,Object... args 并不是某种"高级技巧",

而是 Java 在语言层面为了解决 参数数量不固定 这一常见问题而提供的一种机制。


一、什么是 Object... args?

在 Java 方法定义中:

java 复制代码
public void test(Object... args) {
}

Object... args 被称为 可变参数(Varargs)

一句话概括

Object... args 表示:这个方法可以接收 0 个、1 个或多个参数

它并不是一种新的数据类型,而是 Java 提供的一种 语法糖


二、Object... args 的本质是什么?

1、本质等价于数组

java 复制代码
Object... args

在语义层面上等价于:

java 复制代码
Object[] args

两者的唯一区别在于:

  • 一个是 对调用者友好
  • 一个是 对实现者友好

2、编译器到底帮你做了什么?

你写的代码:

java 复制代码
test(1, "abc", true);

在编译阶段会被转换为:

java 复制代码
test(new Object[]{1, "abc", true});

👉 可变参数本质上就是编译器自动帮你创建数组


三、Object... args 的基本用法

1、方法定义

java 复制代码
public void printArgs(Object... args) {
    for (Object arg : args) {
        System.out.println(arg);
    }
}

2、调用方式(重点)

① 不传任何参数(完全合法)

java 复制代码
printArgs();

等价于:

java 复制代码
printArgs(new Object[]{});

② 传 1 个参数

java 复制代码
printArgs(10);

③ 传多个参数

java 复制代码
printArgs(1, "hello", true);

四、Object... args 在方法内部如何使用?

1、当数组使用(最常见)

java 复制代码
public void test(Object... args) {
    System.out.println(args.length);
}
  • args.length == 0 → 没有传参数
  • args.length > 0 → 至少传了一个参数

2、判断是否传参(实战必用)

java 复制代码
public void test(Object... args) {
    if (args.length == 0) {
        return;
    }
    // 处理参数
}

👉 不需要判空,Java 保证 args 一定不为 null


五、Object... args 的语法规则

1、只能放在参数列表的最后

❌ 错误写法:

java 复制代码
public void test(Object... args, String name) {
}

✅ 正确写法:

java 复制代码
public void test(String name, Object... args) {
}

1、一个方法只能有一个可变参数

❌ 错误示例:

java 复制代码
public void test(Object... a, Object... b) {
}

3、可变参数可以和普通参数共存

java 复制代码
public void test(int id, String type, Object... args) {
}

六、真实业务场景:Spring Boot + Redis Lua

在 Spring Boot 中执行 Redis Lua 脚本时,常见封装方式如下:

java 复制代码
public Long execute(LuaScriptEnum scriptEnum,
                    List<String> keys,
                    Object... args)

1、参数含义说明

参数 含义
scriptEnum 标识使用哪个 Lua 脚本
keys Redis 中的 KEYS
args Redis Lua 中的 ARGV(可选)

2、不传 ARGV 的情况

java 复制代码
execute(
    LuaScriptEnum.STOCK_DEDUCT,
    Collections.singletonList("product:stock:1")
);

Lua 中对应关系:

text 复制代码
KEYS[1] = product:stock:1
ARGV    = 空

3、传 1 个 ARGV

java 复制代码
execute(
    LuaScriptEnum.STOCK_DEDUCT,
    Collections.singletonList("product:stock:1"),
    2
);

Lua 中:

text 复制代码
ARGV[1] = "2"

4、传多个 ARGV

java 复制代码
execute(
    LuaScriptEnum.SOME_SCRIPT,
    Arrays.asList("key1", "key2"),
    10, "abc", true
);

Lua 中:

text 复制代码
ARGV[1] = "10"
ARGV[2] = "abc"
ARGV[3] = "true"

七、Object... args 与 Object[] 的对比

对比项 Object... args Object[]
本质 数组 数组
调用方式 简洁自然 繁琐
是否可省略 ✅ 可以 ❌ 不行
适合场景 API 设计 内部实现

👉 对外暴露的方法,优先使用可变参数


八、常见误区与坑点

1、args 可能为 null?❌

java 复制代码
if (args == null) {
}

👉 没有必要,args 永远不会是 null


2、 传 null 等于不传参数?❌

java 复制代码
execute(enum, keys, null);

实际效果:

text 复制代码
ARGV[1] = "null"

⚠️ 这是传了一个参数,而不是没传


九、总结

为什么优秀的 API 都爱用 Object... args?

  • 参数数量不固定
  • 调用方代码更简洁
  • 向后扩展更友好
  • 非常适合"执行器 / 工具类 / 框架 API"
java 复制代码
execute(script, keys);
execute(script, keys, 1);
execute(script, keys, 1, 2);

Object... args 是 Java 为了解决参数不固定问题而提供的语法糖,
本质仍然是数组,但极大提升了 API 的可用性与可读性。

Spring Boot、Redis Lua、日志框架、测试框架 等场景中,它几乎是不可或缺的设计方式。

相关推荐
qq_58956810几秒前
java基础学习,案例练习,即时通讯
java·开发语言·学习
小何code6 分钟前
人工智能【第8篇】监督学习实战:线性回归与逻辑回归算法详解(万字长文+完整代码实现)
人工智能·python·学习·机器学习·逻辑回归·线性回归
EnCi Zheng8 分钟前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
DevilSeagull10 分钟前
Windows 批处理 (Batch) 编程: 从入门到入土. (一) 基础概念与环境配置
开发语言·windows·后端·batch·语言
逸Y 仙X16 分钟前
文章十九: ElasticSearch Full Text 全文本查询
java·大数据·数据库·elasticsearch·搜索引擎·全文检索
AI科技星16 分钟前
全域数学·第卷:场计算机卷(场空间计算机)【乖乖数学】
java·开发语言·人工智能·算法·机器学习·数学建模·数据挖掘
刘~浪地球20 分钟前
DeepSeek V4 应用实战:构建智能数据分析Agent
python·数据挖掘·数据分析
charlie11451419123 分钟前
嵌入式C++实践开发第21篇(单片机实践):按钮输入 —— 硬件原理、消抖与HAL API
开发语言·c++·单片机
前端老石人24 分钟前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
0xDevNull26 分钟前
Java泛型详解
java·开发语言·后端