文档章节

Java方法的可变参数个数

文文1
 文文1
发布于 2015/06/15 10:48
字数 1058
阅读 63
收藏 0

许多Java新人在看到下面的这段代码的时候,都会问一个问题:dealArray方法里那三个小点点是什么啊?

public class TestVarArgus {  
    public static void dealArray(int... intArray){  
          
    }  
      
    public static void main(String args[]){  
          
    }  
}

这就是今天这篇blog的主角:可变的参数类型,也称为不定参数类型。英文缩写是varargus,还原一下就是variable argument type。通过它的名字可以很直接地看出来,这个方法在接收参数的时候,个数是不定的。那么好,现在就先来调用下这个方法。请看代码和输出:

public class TestVarArgus {  
    public static void dealArray(int... intArray){  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }  
      
    public static void main(String args[]){  
        dealArray();  
        dealArray(1);  
        dealArray(1, 2, 3);  
    }  
}

输出:

1   
1 2 3

通过main方法里的调用,可以看出来这个可变参数既可以是没有参数(空参数),也可以是不定长的。看到这里估计都能明白,这个不定长的参数其实和数组参数挺像的。事实上,也确实是这么回事儿。编译器会在悄悄地把这最后一个形参转化为一个数组形参,并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。请看代码:

dealArray(); //dealArray(int[] intArray{});  
dealArray(1); //dealArray(int[] intArray{1});  
dealArray(1, 2, 3); //dealArray(int[] intArray{1, 2, 3});

说到这里,那么可以来验证一下,利用重载来看看这个可变参数是不是数组类参数?看代码:

public class TestVarArgus {  
    public static void dealArray(int... intArray){  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }  
      
    public static void dealArray(int[] intArray){//会有Duplicate method dealArray(int[]) in type TestVarArgus的错误  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }  
      
    public static void main(String args[]){  
        dealArray();   
        dealArray(1);  
        dealArray(1, 2, 3);  
    }  
}

从上面这段代码可以看出,这两个方法是冲突的,是无法重载的,所以这两个方法的实现原理应该相同。到这里,再来做一个有意思的实验:

//可变参数是兼容数组类参数的
public class TestVarArgus {  
    public static void dealArray(int... intArray){  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }  
      
    public static void main(String args[]){  
        int[] intArray = {1, 2, 3};  
          
        dealArray(intArray);  //通过编译,正常运行  
    }  
}

//数组类参数却无法兼容可变参数
public class TestVarArgus {  
    public static void dealArray(int[] intArray){  
        for (int i : intArray)  
            System.out.print(i +" ");  
          
        System.out.println();  
    }  
      
    public static void main(String args[]){  
        dealArray(1, 2, 3);  //编译错误  
    }  
}

从上面这两段代码可以看出来,可变参数是兼容数组类参数的,但是数组类参数却无法兼容可变参数。其实对于第二段代码而言,编译器并不知道什么可变不可变,在它看来,需要定义一个dealArray(int, int, int)类的方法。所以,自然就无法去匹配数组类参数的dealArray方法了。

既然Java方法接收可变参数,那么接下来我们再来看一下下面的代码:

//可变参数类型必须作为参数列表的最后一项,因为定长形参的优先级大于不定长形参
public class TestVarArgus {  
    public static void dealArray(int count, int... intArray){  
          
    }  
      
    public static void dealArray(int... intArray, int count){//编译报错,可变参数类型应该作为参数列表的最后一项  
          
    }  
      
    public static void main(String args[]){  
            
    }  
}

这段代码说明了,可变参数类型必须作为参数列表的最后一项,而不能放在定长参数的前面。估计你会想到一个词“优先级”。因为没有确切的说明,只是这样一种规定,这里可以借用“优先级”这个词来理解一下,请看下面的代码:

public class TestVarArgus {  
    public static void dealArray(int... intArray){  
        System.out.println("1");  
    }  
      
    public static void dealArray(int count, int count2){  
        System.out.println("2");  
    }  
      
    public static void main(String args[]){  
        dealArray(1, 2);  
    }  
}

代码贴出来估计都知道是输出2,而不是1。记住:能匹配定长的方法,那么优先匹配该方法。含有不定参数的那个重载方法是最后被选中的。


最后,大家都知道main方法的参数就是一个数组类型的,那么它其实也是可以改成不定参数类型。试一试吧,看看有没有编译错误。


本文转载自:

共有 人打赏支持
文文1
粉丝 21
博文 354
码字总数 117825
作品 0
长沙
程序员
私信 提问
阿里java开发规范学习(附P3C IDEA插件 帮助规范的养成)

浅析 阿里巴巴 Java 开发规约 (未完成) contents 为什么要学 编程规约 P3C IDEA 插件 why-use 我们知道,一般稍微大一点的公司,都会在系统架构设计完成之后,编码工作开始之前,给出一份属于自家...

seltonzyf
05/12
0
0
Java高级部分笔记-------Java5.0的新特性

静态导入 1.1 JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法。使用静态导入可以简化程序对类静态属性和方法的调用。 1.2 语法:Import static 包名.类名.静态属性|静态方法|* ...

查封炉台
2014/04/21
0
0
如何唯一确定一个 Java 类?

今天偶然想起之前和朋友讨论过的一个问题:如何唯一确定一个 Java 类?我相信大多数朋友遇到这个问题的回答都是:类的全路径呗。但事实上,唯一确定一个 Java 类,单单靠类路径是不够的,还要...

陈树义
09/14
0
0
Java 程序员必须掌握的 5 个注解!

自 JDK5 推出以来,注解已成为Java生态系统不可缺少的一部分。虽然开发者为Java框架(例如Spring的@Autowired)开发了无数的自定义注解,但编译器认可的一些注解非常重要。 在本文中,我们将...

Java的博客
07/01
0
0
Java中使用Jedis操作Redis

使用Java操作Redis需要jedis-2.1.0.jar,下载地址:http://files.cnblogs.com/liuling/jedis-2.1.0.jar.zip 如果需要使用Redis连接池的话,还需commons-pool-1.5.4.jar,下载地址:http://fil...

脸大的都是胖纸
2015/03/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

linux中常用标识---不定期更新

LINUX常用标识符: 1 & && | || &: 表示进程在后台运行 例如 redis-server & 不是所有后台运行都是& 比如es ./bin/elasticsearch -d es后台运行&&: 第一个命令执行成功后 才执行后面的命令...

geek土拨鼠
43分钟前
1
0
Mybatis 中$与#的区别,预防SQL注入

一直没注意Mybatis 中$与#的区别,当然也是更习惯使用#,没想到避免了SQL注入,但是由于要处理项目中安全渗透的问题,不可避免的又遇到了这个问题,特此记录一下。 首先是共同点: 在mybatis...

大雁南飞了
58分钟前
0
0
Cydia的基石:MobileSubstrate

在MAC与IOS平台上,动态库的后缀一般是dylid,而加载这些动态库的程序叫做dynamic linker(dyld)。这个程序有很多的环境变量来设置程序的一些行为,最为常用的一个环境变量叫做"DYLD_INSERT_...

HeroHY
今天
1
0
Spring Clould负载均衡重要组件:Ribbon中重要类的用法

Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡,而不必在项目里过多地编写实现...

Ala6
今天
0
0
让 linux 删除能够进入回收站

可以参考这个贴子 https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79543316 从那个git地址 把saferm.sh下载下来 把saferm.sh复制到 /usr/bin 目录下 在用~/目下 的.bashrc 下加一句这...

shzwork
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部