课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > 避免带有变长参数的方法重载
  • 避免带有变长参数的方法重载

    发布:昆明Java培训      来源:达内新闻      时间:2016-09-30

  • 昆明Java培训机构的老师发现,在项目和系统开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在JAVA5之前常用的设计技巧就是把形参定义成Collection类型或其子类类型,或者数组类型,这种方法的缺点就是需要对空参数进行判断和筛选,比如实参为null值和长度为0的Collection或数组。而Java5引入了变长参数(varags)就是为了更好地挺好方法的复用性,让方法的调用者可以"随心所欲"地传递实参数量,当然变长参数也是要遵循一定规则的,比如变长参数必须是方法中的最后一个参数;一个方法不能定义多个变长参数等,这些基本规则需要牢记,但是即使记住了这些规则,仍然有可能出现错误,看如下代码:

    1 public class Client {

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

    3        Client client = new Client();

    4        // 499元的货物打75折

    5        client.calPrice(499, 75);

    6    }

    7

    8    //简单折扣计算

    9    public void calPrice(int price, int discount) {

    10        float knockdownPrice = price * discount / 100.0F;

    11        System.out.println("简单折扣后的价格是:" + formatCurrency(knockdownPrice));

    12    }

    13

    14    //复杂多折扣计算

    15    public void calPrice(int price, int... discounts) {

    16        float knockdownPrice = price;

    17        for (int discount : discounts) {

    18            knockdownPrice = knockdownPrice * discount / 100;

    19        }

    20        System.out.println("复杂折扣后的价格是:" + formatCurrency(knockdownPrice));

    21    }

    22

    23    public String formatCurrency(float price) {

    24        return NumberFormat.getCurrencyInstance().format(price);

    25    }

    26 }

    这是一个计算商品折扣的模拟类,带有两个参数的calPrice方法(该方法的业务逻辑是:提供商品的原价和折扣率,即可获得商品的折扣价)是一个简单的折扣计算方法,该方法在实际项目中经常会用到,这是单一的打折方法。而带有变长参数的calPrice方法是叫较复杂的折扣计算方式,多种折扣的叠加运算(模拟类是比较简单的实现)在实际中也经常见到,比如在大甩卖期间对VIP会员再度进行打折;或者当天是你的生日,再给你打个9折,也就是俗话中的折上折。

    业务逻辑清楚了,我们来仔细看看这两个方法,它们是重载吗?当然是了,重载的定义是:"方法名相同,参数类型或数量不同",很明显这两个方法是重载。但是这个重载有点特殊,calPrice(int price ,int... discounts)的参数范畴覆盖了calPrice(int price,int discount)的参数范畴。那问题就出来了:对于calPrice(499,75)这样的计算,到底该调用哪个方法来处理呢?

    我们知道java编译器是很聪明的,它在编译时会根据方法签名来确定调用那个方法,比如:calPrice(499,75,95)这个调用,很明显75和95会被转成一个包含两个元素的数组,并传递到calPrice(int price,int...discounts)中,因为只有这一个方法符合这个实参类型,这很容易理解。但是我们现在面对的是calPrice(499,75)调用,这个75既可以被编译成int类型的75,也可以被编译成int数组{75},即只包含一个元素的数组。那到底该调用哪一个方法呢?运行结果是:"简单折扣后的价格是:374.25"。看来调用了第一个方法,为什么会调用第一个方法,而不是第二个变长方法呢?因为java在编译时,首先会根据实参的数量和类型(这里2个实参,都为int类型,注意没有转成int数组)来进行处理,也就是找到calPrice(int price,int discount)方法,而且确认他是否符合方法签名条件。现在的问题是编译器为什么会首先根据两个int类型的实参而不是一个int类型,一个int数组类型的实参来查找方法呢?

    因为int是一个原生数据类型,而数组本身是一个对象,编译器想要"偷懒",于是它会从最简单的开始"猜想",只要符合编译条件的即可通过,于是就出现了此问题。

    问题阐述清楚了,为了让我们的程序能被"人类"看懂,还是慎重考虑变长参数的方法重载吧,否则让人伤脑筋不说,说不定哪天就陷入这类小陷阱里了。

    了解详情请登陆昆明达内Java培训官网(km.Java.tedu.cn)!

    推荐文章

上一篇:三元操作符的类型务必一致

下一篇:别让null值和空值威胁到变长方法

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:12/29

Java--零基础业余班

Java--零基础业余班

开班日期:12/29

Java--周末提升班

Java--周末提升班

开班日期:12/29

Java--零基础周末班

Java--零基础周末班

开班日期:12/29

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56