1700438528
1700438529
knockdownPrice=knockdownPrice*discount/100;
1700438530
1700438531
}
1700438532
1700438533
System.out.println(“复杂折扣后的价格是:”+formateCurrency(knockdownPrice));
1700438534
1700438535
}
1700438536
1700438537
//格式化成本的货币形式
1700438538
1700438539
private String formateCurrency(float price){
1700438540
1700438541
return NumberFormat.getCurrencyInstance().format(price/100);
1700438542
1700438543
}
1700438544
1700438545
public static void main(String[]args){
1700438546
1700438547
Client client=new Client();
1700438548
1700438549
//499元的货物,打75折
1700438550
1700438551
client.calPrice(49900,75);
1700438552
1700438553
}
1700438554
1700438555
}
1700438556
1700438557
这是一个计算商品价格折扣的模拟类,带有两个参数的calPrice方法(该方法的业务逻辑是:提供商品的原价和折扣率,即可获得商品的折扣价)是一个简单的折扣计算方法,该方法在实际项目中经常会用到,这是单一的打折方法。而带有变长参数的calPrice方法则是较复杂的折扣计算方式,多种折扣的叠加运算(模拟类是一种比较简单的实现)在实际生活中也是经常见到的,比如在大甩卖期间对VIP会员再度进行打折;或者当天是你的生日,再给你打个9折,也就是俗话说的“折上折”。
1700438558
1700438559
业务逻辑清楚了,我们来仔细看看这两个方法,它们是重载吗?当然是了,重载的定义是“方法名相同,参数类型或数量不同”,很明显这两个方法是重载。但是再仔细瞧瞧,这个重载有点特殊:calPrice(int price, int……discounts)的参数范畴覆盖了calPrice(int price, int discount)的参数范畴。那问题就出来了:对于calPrice(49900,75)这样的计算,到底该调用哪个方法来处理呢?
1700438560
1700438561
我们知道Java编译器是很聪明的,它在编译时会根据方法签名(Method Signature)来确定调用哪个方法,比如calPrice(499900,75,95)这个调用,很明显75和95会被转成一个包含两个元素的数组,并传递到calPrice(int price, in..discounts)中,因为只有这一个方法签名符合该实参类型,这很容易理解。但是我们现在面对的是calPrice(49900,75)调用,这个“75”既可以被编译成int类型的“75”,也可以被编译成int数组“{75}”,即只包含一个元素的数组。那到底该调用哪一个方法呢?
1700438562
1700438563
我们先运行一下看看结果,运行结果是:
1700438564
1700438565
简单折扣后的价格是:¥374.25。
1700438566
1700438567
看来是调用了第一个方法,为什么会调用第一个方法,而不是第二个变长参数方法呢?因为Java在编译时,首先会根据实参的数量和类型(这里是2个实参,都为int类型,注意没有转成int数组)来进行处理,也就是查找到calPrice(int price, int discount)方法,而且确认它是否符合方法签名条件。现在的问题是编译器为什么会首先根据2个int类型的实参而不是1个int类型、1个int数组类型的实参来查找方法呢?这是个好问题,也非常好回答:因为int是一个原生数据类型,而数组本身是一个对象,编译器想要“偷懒”,于是它会从最简单的开始“猜想”,只要符合编译条件的即可通过,于是就出现了此问题。
1700438568
1700438569
问题是阐述清楚了,为了让我们的程序能被“人类”看懂,还是慎重考虑变长参数的方法重载吧,否则让人伤脑筋不说,说不定哪天就陷入这类小陷阱里了。
1700438570
1700438571
1700438572
1700438573
1700438575
编写高质量代码:改善Java程序的151个建议 建议5:别让null值和空值威胁到变长方法
1700438576
1700438577
上一建议讲解了变长参数的重载问题,本建议还会继续讨论变长参数的重载问题。上一建议的例子是变长参数的范围覆盖了非变长参数的范围,这次我们从两个都是变长参数的方法说起,代码如下:
[
上一页 ]
[ :1.700438528e+09 ]
[
下一页 ]