Java 的可变参数方法详述
作者:码农小宋 发布时间:2022-06-03 19:12:34
一、可变参数方法的定义
首先看下可变参数方法在代码上是如何定义的,如下所示:
public static void method1(Integer id, String... names) {
System.out.println("id:" + id + " names:" + names.length);
}
通过上面的示例,我们可以看出在定义方法时,在最后一个形参类型后加上三点 …,就表示该形参可以接受多个相同类型的参数值,多个参数值被当成数组传入。
这里我们需要注意几个点:
可变参数只能作为函数的最后一个参数,在其前面可以有也可以没有任何其他参数;
由于可变参数必须是最后一个参数,所以一个函数最多只能有一个可变参数;
Java
的可变参数,会被编译器转型为一个数组;
上面提到可变参数的形式会被编译成一个数组,那么问题来了,我可不可以写两个下面这样的方法呢?
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
已经提示我们这种写法的编译不了的了。
从这里我们可以知道可变参数在编译为字节码后,在方法签名中会以数组形态出现的,导致这两个方法的签名一致的,如果同时出现,是不能编译通过的。
二、可变参数方法的调用
可变参数方法的调用跟其他方法的调用没什么区别,这里要说明的是,我们除了通过可变参数进行调用之外,还可以通过传入数组的形式来进行调用,如下所示:
public static void main(String[] args) {
//直接传递参数
method1(1, "ziyou", "java极客技术");
//通过数组的形式传递参数
String[] array = new String[]{"ziyou", "Java 极客技术", "fdf"};
method1(2, array);
//不传递可变参数
method1(3);
}
通过可变参数和数组的形式,这两种调用形式本质上是一样的;另外可变参数的个数也可以为 0。
三、可变参数方法的重载
试想一下如果我们定义了下面这样的两个方法,定义和使用的时候会是什么情况
public static void method2(String... names) {
System.out.println("111111");
}
public static void method2(String value1, String value2) {
System.out.println("22222");
}
第一个是只有一个可变参数形参的方法;第二个是一个 String 类型的固定参数和第二个参数是可变参数的方法。首先,定义的时候完全没有问题,IDEA 也没有任何错误提示,编译也不会有问题。
那么在使用的时候呢?比如下面这样的写法会输出什么结果呢?
public static void main(String[] args) {
method2("java 极客技术", "ziyou");
}
在看输出结果之前,我们可以看到,main 函数中的调用,其实这两个重载的函数都是可以满足的,而且编译也没有错,那么程序运行会输出什么呢?
通过实际的运行结果我们可以看到,输出的结果是22222
表示运行的是method2(String value1, String value2
) 这个方法,那说明什么问题呢?
说明当存在与可变参数方法形成重载方法的时候的,会优先固定参数的方法进行执行,相信这一点大家应该都从来没有关注过。
写到这里可能有小明要问了,那如果我们第二个方法中的 value2
也是可变参数呢?那这种情况会怎么样呢?为此我们再看一下,下面的这种形式会怎样。
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 的可变参数方法,这样子这个方法不就是可以接受所有类型的参数了吗?就像这样:
public static void method3(Object... objects) {
System.out.println("objects size" + objects.length);
}
首先要说的是,这么定义当然是没有问题的,但是可读性会差很多,调用方完全不知道要传入什么类型;要是真的写了太多像这样的代码,估计维护起来也是害人害己
来源:https://blog.51cto.com/u_15430445/4942670


猜你喜欢
- 关于面向对象和封装的个人理解类和对象类:对事物的一种描述(具有共同属性和行为的事物的抽象),例如手机,属性:品牌价格,行为:玩游戏,刷vx;
- 1.委托delegate委托delegate也是一种类型,在任何可以声明类的地方都可以声明委托,它将方法当做另一个方法的参数进行传递,这样就
- 本文实例为大家分享了java实现人机猜拳游戏的具体代码,供大家参考,具体内容如下完成人机猜拳互动游戏的开发,用户通过控制台输入实现出拳,电脑
- 本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下:我们需要获取Android手机或Pad的屏幕的
- 前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新。该项目实现的就是
- 首次使用idea需要配置哪些东西?最近因为我的eclipse无法配置sts,于是将战场转移至idea,首次使用idea,所有的配置都得重新开
- 本文实例为大家分享了Unity实现弧形移动效果的具体代码,供大家参考,具体内容如下一、实现效果二、第一种实现方法——弧形插值using Un
- 1.前言(基于JDK1.7)最近想把一些java基础的东西整理一下,但是又不知道从哪里开始!想了好久,还是从最基本的jvm开始吧!这一节就简
- 前言想必大家对c语言的动态内存分配并不陌生,忘了的小伙伴也可以看看我的这篇文章C语言动态内存分配c语言的动态内存分配由于有些地方用起来比较麻
- 题目要求思路:模拟解题的核心思想在于逆向思维,不考虑每个子数组中的唯一字符个数,转而考虑每个字符可以作为多少个子数组的唯一字符;所以在计算答
- 前言C# 11 中即将到来一个可以让重视性能的开发者狂喜的重量级特性,这个特性主要是围绕着一个重要底层性能设施 ref 和 struct 的
- 首先给大家来讲一个我们遇到的一个奇怪的问题:1.我的一个springboot项目,用mvn install打包成jar,换一台有jdk的机器
- Fragment Android是在Android 3.0 (API level 11)开始引入Fragment的。 可以把Fragment
- 先给大家展示下效果图,如果大家感觉还不错,请参考实现代码很简单的一个例子,点击刷新验证码,刷新当前显示的验证码,点击确定,如果输入的和显示的
- 一、新建BeanUtil类import lombok.extern.slf4j.Slf4j;import org.springframewo
- 最近在配置OpenCV的时候,由于使用的是VS2019,结果找不到Microsoft.Cpp.X64.user这个文件。导致每次新建项目都得
- 本文以实例描述了C#实现让窗体永远在窗体最前面显示的方法,具体步骤如下:1、新建一个窗体程序,添加一个Timer以及设置它可用并绑定事件。2
- ELK是三款软件的简称,分别是Elasticsearch、Logstash、Kibana组成,在发展的过程中,又有新成员Beats的加入,所
- 旧的设计方案开发api的时候,需要先定义好接口的数据响应结果.如下是一个很简单直接的Controller实现方法及响应结果定义.@RestC
- 本文实例讲述了Java抽象类和抽象方法定义与用法。分享给大家供大家参考,具体如下:一、Java抽象类参考资料:Java抽象类 详解1、抽象类