java开发150个建议( 三 )


因为int是一个原生数据类型,而数组本身是一个对象,编译器想要"偷懒",于是它会从最简单的开始"猜想",只要符合编译条件的即可通过,于是就出现了此问题 。
问题阐述清楚了,为了让我们的程序能被"人类"看懂,还是慎重考虑变长参数的方法重载吧,否则让人伤脑筋不说,说不定哪天就陷入这类小陷阱里了 。
回到顶部
建议5:别让null值和空值威胁到变长方法
上一建议讲解了变长参数的重载问题,本建议会继续讨论变长参数的重载问题,上一建议的例子是变长参数的范围覆盖了非变长参数的范围,这次讨论两个都是变长参数的方法说起,代码如下:
1 public class Client5 {2 3public void methodA(String str, Integer... is) {4 5}6 7public void methodA(String str, String... strs) {8 9}10 11public static void main(String[] args) {12Client5 client5 = new Client5();13client5.methodA("china", 0);14client5.methodA("china", "people");15client5.methodA("china");16client5.methodA("china", null);17}18 }
两个都进行了重载,现在的问题是:上面的.("china");.("china",null);编译不通过,提示相同:方法模糊不清,编译器不知道调用哪一个方法,但这两处代码反应的味道是不同的 。
对于("china")方法,根据实参"china"(类型),两个方法都符合形参格式,编译器不知道调用那个方法,于是报错 。我们思考一下此问题:这个类是一个复杂的商业逻辑,提供了两个重载方法,从其它模块调用(系统内本地调用系统或系统外远程系统调用)时,调用者根据变长参数的规范调用,传入变长参数的参数数量可以是N个(N>=0),那当然可以写成.("china")方法啊!完全符合规范,但是这个却让编译器和调用者郁闷,程序符合规则却不能运行,如此问题,谁之责任呢?是类的设计者,他违反了KISS原则(Keep it Smile,,即懒人原则),按照此设计的方法应该很容一调用,可是现在遵循规范却编译不通过,这对设计者和开发者而言都是应该禁止出现的 。
对于.("China",null),直接量null是没哟类型的,虽然两个方法都符合调用要求,但不知道调用哪一个,于是报错了 。仔细分析一下,除了不符合上面的懒人原则之外,还有一个非常不好的编码习惯,即调用者隐藏了实参类型,这是非常危险的,不仅仅调用者需要"猜测调用那个方法",而且被调用者也可能产生内部逻辑混乱的情况 。对于本例来说应该如此修改:
1 public static void main(String[] args) {2Client5 client5 = new Client5();3String strs[] = null;4client5.methodA("china", strs);5}
也就是说让编译器知道这个null值是类型的,编译即可顺利通过,也就减少了错误的发生 。
建议6:覆写变长方法也循规蹈矩
在JAVA中,子类覆写父类的中的方法很常见,这样做既可以修正bug,也可以提供扩展的业务功能支持,同时还符合开闭原则(Open- ) 。
符合开闭原则(Open- )的主要特征:
1.对于扩展是开放的(Open for ) 。这意味着模块的行为是可以扩展的 。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为 。也就是说,我们可以改变模块的功能 。
2.对于修改是关闭的( for ) 。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码 。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动 。
下面我们看一下覆写必须满足的条件:
覆写方法不能缩小访问权限;参数列表必须与被覆写方法相同;返回类型必须与被重写方法的相同;重写方法不能抛出新的异常,或者超出父类范围的异常,但是可以抛出更少,更有限的异常,或者不抛出异常 。