对付 Java 的可变参数,你真的相识吗?

发布日期:2022-08-07 07:12    点击次数:63

本文转载自微信群众号「Java极客技能」,作者鸭血粉丝Tang。转载本文请联络Java极客技能群众号。

我们都晓得 Java 支持可变参数的模式定义编制,这类语法糖在某些岁月可以或许简化我们的代码,然则对付可变参数是怎么完成的以及别的的更多细节,你真的晓得吗?来日诰日阿粉就带你来相识一下。

可变参数编制的定义

首先看下可变参数编制在代码上是怎么定义的,以下所示:

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);  } 

起重要说的是,这么定义固然是没有成就的,然则可读性会差良多,调用方齐全不晓得要传入什么范例;若是真的写了太多像这样的代码,估量回护起来也是害人害己,这么写的小明就好自为之吧,被解雇了不要说是看了阿粉写的文章学会的。

 



相关资讯