本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议 进行许可。
在Java程序中,方法与属性是类中最基本的成员。下面的问题与方法有关:
实现一个方法的第一步是什么?
说到这里我突然想起侯耀文、赵丽蓉两位艺术家在小品《英雄母亲的一天》中有这样一段台词:
导演:您起床后做的第一件事是什么?可以随便说。
大娘一听可以随便说,笑了。
大娘(凑到导演的耳朵边,轻声地):上厕所。
在这里,我也想做一回导演,把上面的台词改一下:
编程新手:您在实现类中的一个方法时,第一步要做的事是什么?可以随便说。
编程老手一听可以随便说,笑了。
编程老手(凑到新手的耳朵边,轻声地):参数有效性检查。
大娘的回答铁定不是导演希望听到的,编程老手的回答恐怕也不是新手想要得到的。原因很简单,与正题无关。但是参数有效性检查之于方法实现的重要性决不亚于早上起来上厕所,个中原因只可意会,不可言传。这里要讨论的是如何在Java中进行参数有效性检查。
说到参数有效性检查,不得不说一下运行时异常。Java有两种异常:一般异常与运行时异常。继承自Exception的异常称为一般异常,继承自RuntimeException的异常称为运行时异常。与一般异常最大的不同之处在于,函数调用方可以不必处理实现方抛出的运行时异常。 但是异常的抛出通常会被当成一种错误的发生。如果调用方可以不用处理运行时异常,那就意味着调用方必须尽量避免实现方抛出运行时异常。 例如:
public static boolean equalObject(Object obj1, Object obj2) { return obj1.equals(obj2); }
上述代码在obj1为null的场合下会抛出NullPointerException,为了避免这种情况发生,正确的写法应该是:
public static boolean equalObject(Object obj1, Object obj2) { return (obj1 != null && obj1.equals(obj2)); }
可以看出,运行时异常是对函数调用方一种无形的约束,这种约束方式正好符合参数有效性检查的要求,即调用方法时必须提供正确的参数,否则就会导致系统崩溃。例如我们通过物体的质量计算其重力值。实现方法如下:
public class Test { public static void main(String[] args) { System.out.println(getGravity(1.0)); } public static double getGravity(double mass) { return mass * 9.82; } }
我们知道一般情况下一个1.0千克的物体其重力为9.82牛顿,但质量为负数的物体呢?物理常识告诉我们,世界上不存在质量为0或小于0的物体,据此我们应该如何完善重力的计算方法呢?
计算重力的第一步应该是对质量进行参数有效性检查。Java SDK中提供了许多种运行时异常,与参数有效性检查相关的异常是IllegalArgumentException。代码实现可以如下:
public static double getGravity(double mass) { // 参数有效性检查 if (mass <= 0) { throw new IllegalArgumentException("无效质量:" + mass); } return mass * 9.82; }
当我们调用这样一个计算重力的方法时,应该尽量传递有效的质量值。当我们传递一个负值给此方法时,系统将会以抛出异常的方式退出。如:
public class Test { public static void main(String[] args) { System.out.println(getGravity(1.0)); // 有效的质量 // 我们应该尽量避免下面的调用 // System.out.println(getGravity(-1.0)); // 无效的质量 } public static double getGravity(double mass) { // 参数有效性检查 if (mass <= 0) { throw new IllegalArgumentException("无效质量:" + mass); } return mass * 9.82; } }
参数有效性检查应该作为常识来掌握,特别是Java中特有的参数有效性检查。上面介绍的是最基本的用法,当然我们也可以利用第三方程序库(如Apache Commons Lang 库的Validate类)来简化参数有效性检查的过程。