java开发150个建议( 二 )


若两个操作数不可转换,则不作转换,返回值是类型; 若两个操作数是明确类型的表达式(比如变量),则按照正常的二进制数字转换,int转为long,long转为float等; 若两个操作数中有一个是数字S,另外一个是表达式,且其类型标志位T,那么,若数字S在T的范围内,则转换为T类型;若S超出了T的范围,则T转换为S; 若两个操作数都是直接量数字,则返回值类型范围较大者 。
知道什么原因了,相应的解决办法也就有了:保证三元操作符中的两个操作数类型一致,避免此错误的发生 。
建议4:避免带有变长参数的方法重载
在项目和系统开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在JAVA5之前常用的设计技巧就是把形参定义成类型或其子类类型,或者数组类型,这种方法的缺点就是需要对空参数进行判断和筛选,比如实参为null值和长度为0的或数组 。而Java5引入了变长参数()就是为了更好地挺好方法的复用性,让方法的调用者可以"随心所欲"地传递实参数量,当然变长参数也是要遵循一定规则的,比如变长参数必须是方法中的最后一个参数;一个方法不能定义多个变长参数等,这些基本规则需要牢记,但是即使记住了这些规则,仍然有可能出现错误,看如下代码:
1 public class Client {2public static void main(String[] args) {3Client client = new Client();4// 499元的货物 打75折5client.calPrice(499, 75);6}7 8// 简单折扣计算9public void calPrice(int price, int discount) {10float knockdownPrice = price * discount / 100.0F;11System.out.println("简单折扣后的价格是:" + formatCurrency(knockdownPrice));12}13 14// 复杂多折扣计算15public void calPrice(int price, int... discounts) {16float knockdownPrice = price;17for (int discount : discounts) {18knockdownPrice = knockdownPrice * discount / 100;19}20System.out.println("复杂折扣后的价格是:" + formatCurrency(knockdownPrice));21}22 23public String formatCurrency(float price) {24return NumberFormat.getCurrencyInstance().format(price);25}26 }
这是一个计算商品折扣的模拟类,带有两个参数的方法(该方法的业务逻辑是:提供商品的原价和折扣率,即可获得商品的折扣价)是一个简单的折扣计算方法,该方法在实际项目中经常会用到,这是单一的打折方法 。而带有变长参数的方法是叫较复杂的折扣计算方式,多种折扣的叠加运算(模拟类是比较简单的实现)在实际中也经常见到,比如在大甩卖期间对VIP会员再度进行打折;或者当天是你的生日,再给你打个9折,也就是俗话中的折上折 。
业务逻辑清楚了,我们来仔细看看这两个方法,它们是重载吗?当然是了,重载的定义是:"方法名相同,参数类型或数量不同",很明显这两个方法是重载 。但是这个重载有点特殊,(int price ,int... )的参数范畴覆盖了(int price,int )的参数范畴 。那问题就出来了:对于(499,75)这样的计算,到底该调用哪个方法来处理呢?
我们知道java编译器是很聪明的,它在编译时会根据方法签名来确定调用那个方法,比如:(499,75,95)这个调用,很明显75和95会被转成一个包含两个元素的数组,并传递到(int price,int...)中,因为只有这一个方法符合这个实参类型,这很容易理解 。但是我们现在面对的是(499,75)调用,这个75既可以被编译成int类型的75,也可以被编译成int数组{75},即只包含一个元素的数组 。那到底该调用哪一个方法呢?运行结果是:"简单折扣后的价格是:374.25" 。看来调用了第一个方法,为什么会调用第一个方法,而不是第二个变长方法呢?因为java在编译时,首先会根据实参的数量和类型(这里2个实参,都为int类型,注意没有转成int数组)来进行处理,也就是找到(int price,int )方法,而且确认他是否符合方法签名条件 。现在的问题是编译器为什么会首先根据两个int类型的实参而不是一个int类型,一个int数组类型的实参来查找方法呢?