可变参数是编译器实现的语法糖,本质为编译期生成的普通数组;void log(String... msgs) 编译后等价于 void log(String[] msgs),调用时自动封装为数组,方法体内按标准数组操作。

可变参数不是一种新类型,也不是运行时的特殊结构,它只是编译器帮你“自动补数组”的语法糖。
本质是编译期生成的普通数组
你写 void log(String... msgs),编译后实际变成 void log(String[] msgs)。JVM 完全不知道什么叫 “...”,它只看到一个标准的数组参数。反编译 class 文件就能验证:方法签名里没有 varargs,只有 String[];调用处如 log("a", "b") 会被 javac 自动改写为 log(new String[]{"a", "b"})。
调用时零成本转换
传参时无需手动 new 数组,但效果等价:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
log()→ 编译成log(new String[0])(空数组,不是 null) -
log("x")→ 编译成log(new String[]{"x"}) -
log("x", "y", "z")→ 编译成log(new String[]{"x", "y", "z"}) - 已有数组也可直接传:
String[] arr = {"p", "q"}; log(arr);(无需转型)
方法体内就是普通数组操作
进了方法体,msgs 就是标准的 String[],所有数组能力都可用:
立即学习“Java免费学习笔记(深入)”;
- 取长度:
msgs.length - 遍历:
for (String s : msgs)或for (int i = 0; i - 索引访问:
msgs[0](注意判空防越界)
重载时优先选精确匹配
如果有两个方法:print(String s) 和 print(String... s),调用 print("hello") 会绑定前者。只有当没有完全匹配的非 varargs 方法时,编译器才启用 varargs 版本。这点避免了意外降级,也提醒你:不要靠 varargs 做逻辑分支主干。

















