Java可变参数Object... args

2023-11-15

引言

 因为Java要求实参(Arguments)和形参(Parameters)的个数和类型都必须逐一匹配,而形参在定义方法时就已经固定下来了,那么应该如何在Java程序里定义实参个数可变的方法呢?目前有以下三种解决方式:

  1. 方法重载
  2. 数组参数Object[] args
  3. 动态参数/可变参数Object… args

 说明:以上方法实现了实参个数可变,Object实现了参数类型可变。

一、方法重载

 简介:重载允许在同一个类拥有许多只有形参列表不同的方法。然后,由编译器根据调用时的实参来选择到底要执行哪一个方法。
 缺点:尽管可以通过重载机制,为同一个方法提供带有不同数量的形参的版本,但这仍不能达到让实参数量任意变化的目的。
 举例:可以通过重载testOverloading方法,实现传入多种参数的可能。

public class OverloadingSampleA {  
  
    public static void main(String[] args) {  
        testOverloading(1);// 打印出A  
        testOverloading(1, 2);// 打印出B  
    }  
  
    private static void testOverloading(int i) {  
        System.out.println("A");  
    }  
  
    private static void testOverloading(int i, int j) {  
        System.out.println("B");  
    }  
}  

二、Object[] args

 缺点:虽然只需一个方法,但在调用方法时,需要构造数组参数(先声明一个数组,再将参数一个个加到数组中),用起来太麻烦。
 举例:最常见的是main方法,利用一个数组来包裹要传递的实参。

    public static void main(String[] args) {
        
    }

三、Object… args

 J2SE 1.5中提供了Varargs机制(variable number of arguments),允许直接定义能和多个实参相匹配的形参。

3.1 定义

 定义:类型… 参数名
 原理:编译器会把这个形参转化为一个数组形参,并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。
 注意:

  1. 由于存在这样的转化,所以不能再为这个类定义一个和转化后的方法签名一致的方法。
  2. 可变长参数必须是最后一个参数。
  3. 可变参数同时可以跟固定的参数混合使用,但是一个方法的参数中不能同时拥有2种类型的可变参数。

 举例:以下两个方法“等效”,且不能在一个类下同时定义。

private static int sumUp(int... values) {   
}   
private static int sumUp(int[] values) {   
} 

3.2 调用

 注意:“可变个数”也包括0个。
 举例:以下两组调用等效,注意传0个参数时,等效传递一个空数组,而不是null。

sumUp(1, 3, 5, 7); 
sumUp(new int[]{1, 2, 3, 4}); 

sumUp(); 
sumUp(new int[]{}); 

3.3 处理

 说明:处理个数可变的实参的办法,和处理数组实参的办法基本相同。
 举例:直接把int… values当成int[] values处理。

private static int sumUp(int... values) {  
    int sum = 0;  
    for (int i = 0; i < values.length; i++) {  
        sum += values[i];  
    }  
    return sum;  
}  

3.4 传参

 说明:可变参数和数组参数可以相互传参。
 举例:sumUp定义int… values时可传入int[] values,sumUp定义int[] values时,也可传入int… values。

// 方式一
private static int getSumUp(int[] values) {
        return sumUp(values);
    }
    
private static int sumUp(int... values) {  
    int sum = 0;  
    for (int i = 0; i < values.length; i++) {  
        sum += values[i];  
    }  
    return sum;  
}  

// 方式二
private static int getSumUp(int... values) {
        return sumUp(values);
    }
    
private static int sumUp(int[] values) {  
    int sum = 0;  
    for (int i = 0; i < values.length; i++) {  
        sum += values[i];  
    }  
    return sum;  
}  

 注意:不能在调用只支持用数组包裹实参的方法的时候,直接采用这种简明的调用方式,见下面例子。

private static void testOverloading(int[] i) {  
    System.out.println("A");  
}  
 
public static void main(String[] args) {  
    testOverloading(1, 2, 3);// 编译出错  
} 

3.5 泛型

 简介:泛型可以在一定条件下把一个类型参数化。例如,可以在编写一个类的时候,把一个方法的形参的类型用一个标识符(如T)来代表, 至于这个标识符到底表示什么类型,则在生成这个类的实例的时候再行指定。
 说明:泛型不能和可变形参配合使用,但是数组形参不受这个约束的限制。
 举例:T… args报错,T[] args成功。

// 编译出错  
private static <T> void testVarargs(T... args) {  
}  
// 编译通过
private static <T> void testVarargs(T[] args) {  
    for (int i = 0; i < args.length; i++) {  
        System.out.println(args[i]);  
    }  
}  

3.6 重载

 说明:传统上的选择,基本是依照“特殊者优先”的原则来进行。 但是Varargs机制引入之后,完全可以出现两个版本都能匹配,在其它方面也别无二致,只是一个实参个数固定,而一 个实参个数可变的情况。此时,满足“实参个数固定的版本优先于实参个数可变的版本”。
 举例:优先打印A和B,再打印C。

public class OverloadingSampleA {  
  
    public static void main(String[] args) {  
        testOverloading(1);// 打印出A  
        testOverloading(1, 2);// 打印出B  
        testOverloading(1, 2, 3);// 打印出C  
    }  
  
    private static void testOverloading(int i) {  
        System.out.println("A");  
    }  
  
    private static void testOverloading(int i, int j) {  
        System.out.println("B");  
    }  
  
    private static void testOverloading(int i, int... more) {  
        System.out.println("C");  
    }  
}  

 注意:可能会有两个版本都能匹配,在其它方面也如出一辙,而且都是实参个数可变的冲突发生。

public class OverloadingSampleB {  
  
    public static void main(String[] args) {  
        testOverloading(1, 2, 3);// 编译出错  
    }  
  
    private static void testOverloading(Object... args) {  
    }  
  
    private static void testOverloading(Object o, Object... args) {  
    }  
} 

参考

java学习之九:方法中Object… args参数的含义
java中 Object… args 的理解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java可变参数Object... args 的相关文章

  • Maven 2:如何将当前项目版本打包在WAR文件中?

    我正在使用 Maven 2 构建我的 Java 项目 并且正在寻找一种向用户呈现 pom xml 当前版本号的方法 例如使用 Servlet 或 JSP 据我所知 最好的方法是 Maven 将版本号作为文本文件打包到 WAR 中 这使我能够
  • Hashmap并发问题

    我有一个哈希图 出于速度原因 我希望不需要锁定 假设我不介意过时的数据 同时更新它和访问它会导致任何问题吗 我的访问是获取 而不是迭代 删除是更新的一部分 是的 这会导致重大问题 一个例子是向散列映射添加值时可能发生的情况 这可能会导致表重
  • Google App Engine with Java - 运行 javac.exe 编译器时出错

    在 Windows XP 上 刚刚下载并解压谷歌应用程序引擎java sdk to C Program Files appengine java sdk 我已经安装了jdk C Program Files Java jdk1 6 0 20
  • Java、Oracle 中索引处缺少 IN 或 OUT 参数:: 1 错误

    您好 我使用 Netbeans 8 0 2 和 Oracle 11g Express Edition 在 JSF 2 2 中编写了一个图书馆管理系统 我有几个名为 书籍 借阅者 等的页面 以及数据库中一些名为相同名称的表 我的问题是这样的
  • 将过滤器添加到 Eclipse 中的 Project Explorer

    我想向 Project Explorer 添加一个新的过滤器 以向用户隐藏一些在 Eclipse RCP 应用程序中自动创建的项目 到目前为止我已经找到了两个扩展点 org eclipse ui ide resourceFilters 允许
  • java.lang.LinkageError:尝试重复的类定义

    为什么会发生错误以及如何修复它 02 13 02 pool 4 thread 2 WARN Exception in thread pool 4 thread 2 02 13 02 pool 4 thread 2 WARN java lan
  • Java Microsoft Excel API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • 如何导入 org.apache.commons.lang3.ArrayUtils;进入 Eclipse [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我如何导入 org apache commons lang3 ArrayUtils 将库添加到 Ecl
  • 从 @JsonProperty 值获取枚举常量

    我有一个标有 JsonProperty 的枚举 用于使用 Jackson 进行 JSON 序列化 反序列化 并且希望获取给定字符串 JsonProperty 的枚举值 public enum TimeBucket JsonProperty
  • 发生错误。请参阅日志文件 - eclipse juno

    每当我启动 Eclipse Juno 时 都会出现错误 发生错误 请查看日志文件 C Program Files eclipse configuration 1362989254411 log 有的网站说卸载jdk重新安装 我这样做了 但没
  • 带有 OpenId 提供程序的 Java Spring 安全性

    我有一个 spring MVC 应用程序 另一个客户端应用程序想要使用 open id connect 访问我的 spring 应用程序 如何在服务器端实现开放ID提供商 请帮忙 MITREid 连接 OpenID Connect Java
  • 改变for循环的顺序?

    我遇到一种情况 我需要根据用户输入以不同的顺序循环遍历 xyz 坐标 所以我是 3D 空间中的一个区域 然后是一组像这样的 for 循环 for int x 0 x lt build getWidth x for int y 0 y lt
  • 如何在Java媒体框架中学习.wav持续时间?

    我正在尝试使用 java 媒体框架将 mov 文件与 wav 文件合并 因此我需要知道它们的持续时间 我怎样才能做到这一点 任何想法 将不胜感激 您可以使用以下方式了解声音文件的持续时间 即 VitalyVal 的第二种方式 import
  • 为什么我的代码会产生错误:该语句没有返回结果集[重复]

    这个问题在这里已经有答案了 我正在从 Microsoft SQL Server Studio 执行以下查询 该查询工作正常并显示结果 SELECT INTO temp table FROM md criteria join WHERE us
  • 无法使用 wget 在 CentOS 机器上安装 oracle jdk

    我想在CentOS上安装oracle java jdk 8 我无法安装 java jdk 因为当我尝试使用命令安装 java jdk 时 root ADARSH PROD1 wget no cookies no check certific
  • 摩尔斯电码 至 英语

    我现在的问题是让 摩尔斯电码转英语 正常工作 将英语转换为莫尔斯电码的第一部分工作正常 我知道以前已经有人问过这个问题 但我不知道我做错了什么 我知道我需要在某个地方进行拆分 但我只是不确定将其放在代码中的何处 现在 莫尔斯电码到英语的部分
  • 为什么范围为“provided”的依赖项会隐藏 Maven 中的传递依赖项?

    我的 Maven 项目中有三个模块 这稍微简化了 model包含JPA注释的实体类 坚持实例化一个实体管理器并调用它的方法 应用创建类的实例model 设置一些值并将它们传递给坚持 model and 坚持显然取决于javax persis
  • 如何在不同版本的Google App Engine中使用自定义域名?

    我使用谷歌应用程序引擎作为我的 Android 和 Web 应用程序的服务器 我使用 Android Studio 开发了 Android 应用程序 并使用 Eclipse 开发了 Web 应用程序 我在应用程序引擎中部署了两个版本 第一个
  • Java、Spring、Hibernate找不到org.springframework.orm.hibernate3.LocalSessionFactoryBean

    我正在尝试制作 spring hibernate ant 项目 目前我收到此错误 HTTP Status 500 type Exception report message description The server encountere

随机推荐

  • Centos5.8 x86_64下安装DRBD+Heartbeat+NFS

    实验环境 vmware workstation os Centos5 8 x86 64 编辑两台虚拟机分别新增一块网卡作为心跳检测 新增一块4G的硬盘 大小保持一致 两台机器的基本情况如下所示 centos1 mypharma com 19
  • python之路 第三章 逻辑判断语句——布尔类型和比较运算符、if语句、if else、if elif else、嵌套

    目录 第三章 逻辑判断语句 01 布尔类型和比较运算符 02 If语句的基本格式 03 if else语句 04 if elif else组合使用的语法 05 判断语句的嵌套 第三章 逻辑判断语句 01 布尔类型和比较运算符 在生活中 我们
  • Feign接口方法返回值设置

    Feign接口方法返回值设置 一 介绍 随着微服务的广泛应用 越来越多的企业都会使用微服务进行项目开发 在各个服务之间需要通过feign来进行通信 所以在feign调用接口中方法会接受其他服务接口不同类型返回值 二 返回值设置 1 依据被调
  • el-table实现跨页全选

    el table实现跨页全选 在开发中 我们会遇到一些需要全选表格的需求 由于我们使用了后端分页 在选中时需要维护一个数组 便于回写 但是我们有时需要跨页全选 一个按钮选中所有 我们维护的数组如果从后台拿到所有数据去维护的话这样我们的性能就
  • idea中回退git历史版本并删除历史提交记录

    本篇文章主要介绍git在idea中的回退历史版本 适用场景为代码提错分支 正常回退版本都可适用 回退前先检查一下本地分支是否和远程分支对应 否则会失败 1 打开idea中git历史提交窗口 快捷键 alt 9 有改动则是自己改的快捷键 2
  • 逍遙安卓和Charles實現https抓包

    Charles是一款来自国外的非常强大抓包神器 具有十分简洁的界面 直观易用 通过这款软件可以帮助用户方便地进行抓包 它可以轻松记录浏览器和Internet之间的所有流量 是非常专业并基于java开发网络http抓包工具软件 非常适合开发人
  • conda使用详细

    目录 Anaconda环境变量 一 常用命令 1 创建Python虚拟环境 2 切换环境 3 对虚拟环境中安装额外的包 4 关闭虚拟环境 即从当前环境退出返回使用PATH环境中的默认python版本 5 删除虚拟环境 6 克隆虚拟环境 7
  • 教你如何简单的在windows 10使用Debug

    很多有Windows 10 系统的小伙伴都想要学习汇编 那么怎样搭建debug环境好呢 小编发现 很多这种类似的教程都是叫你去安装Dosbox 这就有一篇教你用用这种方法搭建的 但是不好的事那个界面有点让小编看着不舒服 当然你也可以选择使用
  • 移动端开发同后端交互安全机制记录

    前言 这两年移动端开发的热度明显不如前几年 而且混合式开发框架诸如appcan的兴起在一定程度上降低了移动端开发的门槛 而最近更加流行的React开发更是把移动端原生开发的热度拉低很多 基于React Native构建的移动APP无论是在体
  • Chrome 和 Chromium 区别

    Chromium Chromium 官网 https www chromium org Chromium 源码 https github com chromium chromium Chromium是谷歌的开源项目 由开源社区维护 拥有诸多
  • 支付宝妥协被银联“收编” 网联“尴尬”吗?

    据上海证券报从知情人士处证实 中国银联与支付宝已于9月10日举行内部签约仪式 就支付清算业务达成了相关合作 这也意味着 两大支付巨头 支付宝和微信支付均被合法清算组织 银联和网联 收编 对此 银联和支付宝方面昨日均表示 不作回应 但值得注意
  • 解决错误提示“error: #5: cannot open source input file “core_cmInstr.h“: No such file or directory“方法

    今天来分享一个我们在初期开发单片机时候遇到的一个很常见的错误 就是提示 error 5 cannot open source input file core cmInstr h No such file or directory 错误信息
  • AIGC数字人直播 ChatGPT MDJOURNey技术学习待续

    AIGC数字人直播 ChatGPT MDJOURNey技术学习待续
  • 第四届蓝桥杯JavaB组省赛-黄金连分数

    第四届蓝桥杯JavaB组省赛 黄金连分数 题目描述 题目描述 黄金分割数0 61803 是个无理数 这个常数十分重要 在许多工程问题中会出现 有时需要把这个数字求得很精确 对于某些精密工程 常数的精度很重要 也许你听说过哈勃太空望远镜 它首
  • 开源人脸识别引擎SeetaFace(一)

    SeetaFace Engine是一个开源的C 人脸识别引擎 它可以在不依赖第三方的条件下载CPU上运行 他包含三个关键部分 即 SeetaFace Detection SeetaFace Alignment和SeetaFace Ident
  • 王道——计算机网络

    第一章 以太网典型网络 协议 网络设备 网络体系结构 计算机网络 概念 网络包含计算机网络 计算机网络 分散的具有独立功能的计算机系统 通过通信设备与线路连接起来 由功能完善的软件实现资源共享和信息传递的系统 在端系统上安装软件 实现资源共
  • Vue3使用v-for按需遍历多选框按钮

    目录 前言 1 template 2 Setup 3 效果 前言 Vue3 setup语法糖 v for按需遍历 记录两次数据的diff算法 用来判断是否发起请求 按需提取源数据内容遍历 1 template template div h1
  • CPU高速缓存SRAM命中问题的总结与实验

    1 SRAM高速缓存的结构 获取本机CPU的SRAM缓存信息 我使用的是一个叫cpuinfo x86的小程序 可以获取x86架构的cpu相关信息 下载地址 http osxbook com book bonus misc cpuinfo x
  • 重定向和转发的区别

    重定向和转发的区别 在代码上 转发 第一步 获取请求转发器对象 RequestDispatcher dispatcher request getRequestDispatcher b 第二步 调用转发器的forward方法完成跳转 转发 d
  • Java可变参数Object... args

    文章目录 引言 一 方法重载 二 Object args 三 Object args 3 1 定义 3 2 调用 3 3 处理 3 4 传参 3 5 泛型 3 6 重载 参考 引言 因为Java要求实参 Arguments 和形参 Para