Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >关于 Java 的可变参数你真的了解吗?

关于 Java 的可变参数你真的了解吗?

作者头像
Java极客技术
发布于 2022-12-04 02:09:59
发布于 2022-12-04 02:09:59
51500
代码可运行
举报
文章被收录于专栏:Java极客技术Java极客技术
运行总次数:0
代码可运行

我们都知道 Java 支持可变参数的形式定义方法,这种语法糖在某些时候可以简化我们的代码,但是关于可变参数是如何实现的以及其他的更多细节,你真的知道吗?今天阿粉就带你来了解一下。

可变参数方法的定义

首先看下可变参数方法在代码上是如何定义的,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void method1(Integer id, String... names) {
      System.out.println("id:" + id + " names:" + names.length);
}

通过上面的示例,我们可以看出在定义方法时,在最后一个形参类型后加上三点 ,就表示该形参可以接受多个相同类型的参数值,多个参数值被当成数组传入。这里我们需要注意几个点:

  1. 可变参数只能作为函数的最后一个参数,在其前面可以有也可以没有任何其他参数;
  2. 由于可变参数必须是最后一个参数,所以一个函数最多只能有一个可变参数;
  3. Java 的可变参数,会被编译器转型为一个数组;

上面提到可变参数的形式会被编译成一个数组,那么问题来了,我可不可以写两个下面这样的方法呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void method1(Integer id, String... names) {
    System.out.println("id:" + id + " names:"+ names.length);
}

public static void method1(Integer id, String[] names) {
    System.out.println("id:" + id + " names:" + names.length);
}

在一个类中的定义相同名字的一个可变参数的方法和一个包含数组的方法,写完过后我们就发现 IDEA 已经提示我们这种写法的编译不了的了。

从这里我们可以知道可变参数在编译为字节码后,在方法签名中会以数组形态出现的,导致这两个方法的签名一致的,如果同时出现,是不能编译通过的。

可变参数方法的调用

可变参数方法的调用跟其他方法的调用没什么区别,这里要说明的是,我们除了通过可变参数进行调用之外,还可以通过传入数组的形式来进行调用,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void main(String[] args) {
        //直接传递参数
        method1(1, "ziyou", "java极客技术");
        //通过数组的形式传递参数
        String[] array = new String[]{"ziyou", "Java 极客技术", "fdf"};
        method1(2, array);
        //不传递可变参数
        method1(3);
}

通过可变参数和数组的形式,这两种调用形式本质上是一样的;另外可变参数的个数也可以为 0。

可变参数方法的重载

试想一下如果我们定义了下面这样的两个方法,定义和使用的时候会是什么情况

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void method2(String... names) {
        System.out.println("111111");
}

public static void method2(String value1, String value2) {
        System.out.println("22222");
 }

第一个是只有一个可变参数形参的方法;第二个是一个 String 类型的固定参数和第二个参数是可变参数的方法。首先,定义的时候完全没有问题,IDEA 也没有任何错误提示,编译也不会有问题。

那么在使用的时候呢?比如下面这样的写法会输出什么结果呢?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void main(String[] args) {
        method2("java 极客技术", "ziyou");
}

在看输出结果之前,我们可以看到,main 函数中的调用,其实这两个重载的函数都是可以满足的,而且编译也没有错,那么程序运行会输出什么呢?

通过实际的运行结果我们可以看到,输出的结果是22222 表示运行的是method2(String value1, String value2) 这个方法,那说明什么问题呢?

说明当存在与可变参数方法形成重载方法的时候的,会优先固定参数的方法进行执行,相信这一点大家应该都从来没有关注过。

写到这里可能有小明要问了,那如果我们第二个方法中的 value2 也是可变参数呢?那这种情况会怎么样呢?为此我们再看一下,下面的这种形式会怎样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void method2(String... names) {
        System.out.println("111111");
    }

    public static void method2(String value1, String value2) {
        System.out.println("22222");
    }

    public static void method2(String value1, String... value2) {
        System.out.println("33333");
    }

首先定义的时候 IDEA 没有任何错误提示,说明编译是没有问题的,那调用的时候呢?

可以看到这个时候 IDEA 已经提示我们匹配到多个方法合适的方法,不能编译通过,主要是第一个和第三个方式的写法导致的,匹配到了多个可变参数的方法,我们日常开发的时候要注意这个问题。

Object 可变参数

看到这样有小明就要问了,那我可不可以创建一个基于 Object 的可变参数方法,这样子这个方法不就是可以接受所有类型的参数了吗?就像这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static void method3(Object... objects) {

        System.out.println("objects size" + objects.length);

}

首先要说的是,这么定义当然是没有问题的,但是可读性会差很多,调用方完全不知道要传入什么类型;要是真的写了太多像这样的代码,估计维护起来也是害人害己,这么写的小明就好自为之吧,被开除了不要说是看了阿粉写的文章学会的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java极客技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数
在Java编程中,可变参数是一项强大的功能,它允许你编写更加灵活的方法,接受不定数量的参数。本文将详细解释Java可变参数的用法、语法以及最佳实践。
繁依Fanyi
2023/10/12
1.4K0
【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数
灵魂拷问:Java的可变参数究竟是怎么一回事?
在逛 programcreek 的时候,我发现了一些专注基础但不容忽视的主题。比如说:Java 的可变参数究竟是怎么一回事?像这类灵魂拷问的主题,非常值得深入地研究一下。
沉默王二
2019/12/30
7490
Java基础:五、可变参数列表 (9)
由于所有的类都直接或间接继承于Object类,所以可以创建以Object数组为参数方法,以此获取可变参数列表
桑鱼
2020/03/17
4750
Java 可变参数
Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项。当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。
MonroeCode
2018/01/11
1.7K0
Java 可变参数
上例程序实现的是一个方法接受不同长度的数据内容,并将内容值进行累加处理;之所以使用数组,是因为多个参数无法具体的描述,只可以用数组的方式来接收多个不定的参数。
Mirror王宇阳
2020/11/10
1.1K0
深度解析Java可变参数类型以及与数组的区别
这篇文章主要介绍了Java方法的可变参数类型,通过实例对Java中的可变参数类型进行了较为深入的分析,需要的朋友可以参考下。
用户1289394
2021/01/20
7120
深度解析Java可变参数类型以及与数组的区别
Java中的可变参数_Effective Java 2.0_Item 2知识点
在JDK 1.5之前,要想在方法中使用可变参数,则必须通过数组(或其它集合)来实现,在这种情况下你需要将变量显式的定义在数组中,在使用时要从数组中取出变量。另一种方法是进行函数重载。而在JDK 1.5中,引入了可变参数(Varargs),全称为variable number of arguments,常被称为variable arguments。可变参数仍然是通过数组来实现的,只不过编译器帮你隐式的实现了这个过程,此外,它还能兼容以前的API。
Tyan
2022/05/09
3160
【JavaSE】可变参数的基本使用
可变参数 1. 基本概念 Java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法 就可以通过可变参数实现 2. 基本语法 访问修饰符 返回类型 方法名(数据类型... 形参名) { } 3. 快速入门案例 VarParameter01.java 看一个案例 类 XdrMethod,方法 sum 【可以计算 2 个数的和,3 个数的和 , 4. 5, ...】 public int sum(int n1, int n2){ return n1 + n2; }
兮动人
2021/12/30
4400
JDK5泛型和可变参数
泛型和可变参数在我们学习类,集合时是必不可缺的,我们可以通过泛型和可变参数简化编译代码以便于更好地达到目的
秋落雨微凉
2022/10/25
2510
【JavaSE专栏35】可变参数的那些事,以不变应万变
本文讲解了 Java 中可变参数的知识,给出了可变参数的定义语法、应用场景和面试题,并给出了样例代码
Designer 小郑
2023/08/02
3100
【JavaSE专栏35】可变参数的那些事,以不变应万变
java的可变参数和foreach循环需要注意的坑
但是用int... a,这个参数可以不填,切记!不传入参数时数组a不是null,数组a是一个长度为0的int数组。除非显式传入null参数。
砖业洋__
2023/05/06
3570
java的可变参数和foreach循环需要注意的坑
一文读懂《Effective Java》第42条:慎用可变参数
在Java1.5发行版中,加入了可变参数列表方法,称为variable arity method(可匹配不同长度的变量的方法)。
后台技术汇
2022/05/28
3280
一文读懂《Effective Java》第42条:慎用可变参数
大数据必学Java基础(二十七):详述main方法和了解可变参数
程序的入口,在同一个类中,如果有多个方法,那么虚拟机就会识别main方法,从这个方法作为程序的入口
Lansonli
2022/07/21
2410
大数据必学Java基础(二十七):详述main方法和了解可变参数
坑爹的 Java 可变参数,把我整得够惨。。
就是方法参数用 Object... args 三个点形式,一个参数可以接收多个参数。
Java技术栈
2019/06/14
6910
面试突击13:方法优先调用可选参数还是固定参数?
可选参数(varargs)是 JDK 5 中新增的特性,也叫变长参数或可变参数。它是指一个方法的参数中可以用“...”来表示此方法可以接受无穷个参数,这种表示方法就叫可选参数。 可选参数的语法如下:
磊哥
2022/05/09
6510
面试突击13:方法优先调用可选参数还是固定参数?
16(03)总结增强for循环,静态导入,可变参数
3:增强for循环(掌握) (1)是for循环的一种 (2)格式: for(元素的数据类型 变量名 : 数组或者Collection集合的对象) { 使用该变量即可,该变量其实就是数组或者集合中的元素。 } (3)好处: 简化了数组和集合的遍历 (4)弊端 增强for循环的目标不能为null。建议在使用前,先判断是否为null。 package cn.itcast_01; import java.util.ArrayList; import java.util.List; /* * JD
Java帮帮
2018/03/15
1.3K0
【译】golang 可变参数函数终极指南
Ultimate Guide to Go Variadic Functions 原文地址 https://blog.learngoprogramming.com/golang-variadic-funcs-how-to-patterns-369408f19085
goodspeed
2020/12/22
3.5K0
【译】golang 可变参数函数终极指南
Java基础入门笔记04——方法调用,方法重载,命令行参数,可变参数,多维数组,Arrays类,冒泡排序,矩阵的压缩存储
一般情况:写几个名字一样的方法(方法名必须相同),让它们的参数类型不同(一定不同),参数个数可以不同,参数顺序可以不同,方法体也可以不同。
全栈程序员站长
2022/09/21
7140
Java基础入门笔记04——方法调用,方法重载,命令行参数,可变参数,多维数组,Arrays类,冒泡排序,矩阵的压缩存储
C/C++开发基础——可变参数与可变参数模板
1.如果可变参数的参数类型相同,可以使用标准库中的initializer_list。
Coder-ZZ
2023/09/04
7170
C/C++开发基础——可变参数与可变参数模板
第32项:谨慎地结合泛型和可变参数(Combine generics and varargs judiciously)
可变参数方法(第53项)和泛型都在Java 5时添加到了平台中,所以你可能会期望它们会优雅地相互作用;可悲的是,它们不能相互作用。可变的目的是允许客户端将数量可变的参数传递给方法,但它是一个漏洞抽象( leaky abstraction):当你调用可变参数方法时,会创建一个数组来保存可变参数;该数组应该是一个实现细节,是可见的。因此,当可变参数具有泛型或者参数化类型时,会出现令人困惑的编译器警告。
用户7886150
2020/12/14
1.4K0
推荐阅读
相关推荐
【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验