Java Varargs机制解决不定量参数问题

    看Android的EasyPermission开源库时,发现申请不定数目的权限时用到了一个Object... receivers的形参来设置申请权限结果的接收者,从来没见过,就稍微学习了一下怎么个意思。

    进入正题。Java编程中,很多时候会遇到参数个数不定的情况,比如命令行传参数,比如上面说的EasyPermission运行时权限。这种情况难以用重载满足不定个数实参的需求,传统的处理方法是用数组将实参包装起来,然后形参放一个数组来满足需求,但调用时不够简洁,要经过一步包装。

    于是,J2SE 1.5中Varargs机制应运而生,“Varargs”是“variable number of arguments”的意思,允许直接定义能和不定个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。只要在参数定义的括号里写上一个形参的“类型”与“参数名”之间加上三个连续的“.”(即“...”,英文里的句中省略号),就可以让它和不确定个实参相匹配。而一个带有这样的形参的方法,就是一个实参个数可变的方法。顺便放上问题的根源——

EasyPermissions.onRequestPermissionsResult
public static void onRequestPermissionsResult(int requestCode,
                                                  @NonNull String[] permissions,
                                                  @NonNull int[] grantResults,
                                                  @NonNull Object... receivers) {
        // Make a collection of granted and denied permissions from the request.
        //...
    }

    但这样做有很多隐患,比如int sum(int...somevalues , int...othervalues)这种,给你个sum(1,2,3,4,5);,根本无法确定这几个参数哪些属于somevalues,哪些属于othervalues; 再比如int sum(int ...values){//methord}和重载方法int sum(int a , int b){//another methord},整出来个这样的调用sum(2 , 3);,编译器也搞不清你到底想用哪种方法。

     于是推出Varargs的同时,也相应制定了很多约束,下面进行说明。

原理

    虽然没有详细地看底层实现,但通过博客什么的也稍微了解了一下原理。其实说白了Varargs最后还是把不定个数的参数通过编译器进行了数组转换,并在编译出的class文件里作上一个记号表明这是个实参个数可变的方法。如果传入的是这种形式sum(1,2,3,4);就转换成数组,如果传入的就是数组则省略这一步,而且支持空数组或者缺省参数实现0个参数的传入。这样就不需要开发者自己写数组包装的语法了。


约束

    1.只有最后一个形参能被定义成“能和不确定个实参相匹配”的可变形参,其他参数要有的话需要放在前面

        

    2.由于必须放在最后面,而每串参数只能有一个是“在最后面的”,因此一个方法中只能有一个这样的参数


    3.由于最终会被编译器转换成数组,因此不可以有 “其他参数不变,不定量形参替换为数组类型” 的重载方法


    4.传入数组是合法的,但会提示多此一举



    5.不可以定义把编译器搞蒙的重载方法,否则定义方法时不会报错,但调用时会提示造成了歧义。

             (Ambiguous  adj.   模棱两可; 含糊的,不明确的; 引起歧义的; )


    6.Varargs引入后,重载时的方法选择也有了歧义现象,这时会先选择固定参数个数的方法,然后考虑可变个数参数的方法。






*注:第6点有些费解,注意几个方法参数类型的区别,自己建个java文件敲一敲看看结果,也不算很难懂

    7.换个角度,我们可以通过添加固定参数解决冲突问题。但此时固定参数的类型应与可变个数参数有所区别,否则会报错,错误类型与第5条类似。




小结

    差不多就这样了,但我感觉虽然固定参数个数能解决重载方法歧义问题,但最好还是尽一切可能不要出现有歧义的地方,就算机器不报错解决了冲突,但代码也要给人读啊,秀这么一下别人读起来很费劲的
















  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值