随笔 - 17  文章 - 49  trackbacks - 0
<2006年9月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(1)

随笔分类(17)

随笔档案(17)

相册

最新随笔

搜索

  •  

最新评论

阅读排行榜

评论排行榜

2006 929 星期五

检查方法参数,平凡处的学问

-effective java item 23


    大多数方法和构造器都对参数有一定的限制要求,然而有否显式地检查参数就因人而异,回想自己的编码历程,也常在兴冲冲之际,直接奔向业务逻辑。然而这个看似平凡的小地方,却应该养成一个坚固的习惯,小小付出带来的效果事实上相当可观。

若有非法的参数传入,加以检查,则会立刻引发意义明确的异常。相反,若无此检查,后续情形大相径庭。该方法可能在某一行猝死,死因报告相当迷离;更劣者,方法最后寿终正寝,返回的却是错误的计算结果;最劣者,顺利走完并返回正确的结果,但执行的过程某些牵涉到的对象被设置成不正确的状态,这些隐患最后爆发于无法预计的时刻和地点。

因而,检查参数的正确性这一举动带来的贡献,更多的是来源于这一举动若不存在时可能带来的麻烦,这扇大门过于开放,则带来日后清理门户时过多的周折。

除去检查需要进行计算的参数,更要注意检查在本方法中并未使用但存储起来以备后用的参数,若不加检查,等到异常发生的时候,来源难以追踪。大大增加了debug的痛苦,这一点,想必很多coder会有这样的郁闷回忆。构造方法是这种情形的典型,构造器的大多数参数是属于这种“以备后用”的类型。错误的参数可能导致类的逻辑规则被破坏,此后导致的异常可能非常奇怪而且难以理清缘由。

凡事必有例外。某些情形下,参数检查是不应该执行的,例如这种检查代价昂贵或者不切实际,而且,(注意,是而且)合法性的检查在计算的过程中隐式的进行。例如一个对list里的object进行排序的方法,这些object必须是相互可比较的,否则,比较过程中就会抛出ClassCastException,这也正是排序方法应该抛出的异常,因而事先进行可比性的检查就无意义了。但如果不谨慎的使用这种隐式检查的技巧,就会损失错误的原子性,比如这个方法不仅仅是比较,而且还进行写操作,那么中途抛出异常的时候,已经有某些数据被改动了,你不得不进行roll back,否则就要接受一个半成品。这一方面在item 46里有更多的描述。另外,有时候这种隐式的检查所抛出的异常,也可能并非真正的病因,你还需要做些异常的“翻译”来指引真实的问题根源。

以上所说并非鼓励你限制参数,事实上,只要方法本身能应付得来,就应该尽量放宽参数的限制,方法才能有通用性。

总而言之,每当你写一个方法或构造器,就应该考虑会有什么限制需要加之于参数上,为此配上文档说明,在方法一开始就显式检查,养成这样的习惯很重要,这一点点谨慎的工作,在这个方法第一次抛出参数异常的时候,就开始了对你的回报。


Friday, September 29, 2006

Check method parameters for validity, knowledge within a trivial spot

     -effective java item 23

 

Most of methods and constructors have constraints on their parameters, but whether carry out a validity check differs from people to people. Recalling my own programming experience, I did rush to implement the business without making a check. But rigid habit shall be kept here, the little effort really brings back a lot.

If an invalid parameter is passed into a method with checking, a prompt and clear exception will be thrown, the situation can be quite different without a check. The method may fail somewhere on the way, reporting a confusing exception or error; to be worse, the method executed successfully, but giving back a wrong result, and the worst one, the method end with a correct result, but corrupted some relevant objects during the process, and these latent problems will break out somewhere or sometime you never know.

Therefore, the benefits of checking for validity actually comes from the fact that possibly lots of problems will appear without the checking. The door was too open and brings too much threat to future situation.

Besides checking parameters for calculation, more attention shall be put on the checking on parameters that are stored for later use. Without the checking, errors will occur sometime when the original instances are difficult to trace, which brings miserable experience to the debugging process. I supposed quite a lot of coders had tasted that. Constructors are a representative case, most of the parameters of constructors are for later uses, invalid parameters will violate invariants of the class, the exception it caused can be very weird and hard to solve.

There is exception. In some case which validity checking is expensive or impractical and the check can be perform implicitly in the process of calculation. For instance, a method sorting a list, for such a method, the objects in the list must be mutually comparable, otherwise a ClassCastException will be thrown, and it is exactly the exception a sorting methods should throws, so it will be meaningless to check them ahead of time. However, indiscriminate application of such techniques can lead to the loss of failure atomicity. For example, the method does more than sorting, it also do some writing operation of the objects, in such case, by the time an exception is thrown, some of the objects have already been modified, you have to roll back, or, accept a half complete result. This is discussed in detail in item 46. What’s more, sometimes exception thrown by implicit check can not tell the really problems, and you have to do some “exception translating” for revealing the real cause.

The above information does not means that arbitrary restrictions on parameters are a good thing. In fact, you shall put fewer restrictions on them as long as the method is capable of dealing the parameters. By this way we get more general methods.

To summarize, you shall consider what restrictions should exist on the parameters when you are writing a method or constructor, and document for them, apply explicit check in the beginning of the method body, it is important to get into the habit of doing this, this modest work will start pay back at the first time a validity check fails.

posted on 2006-09-29 13:36 Ye Yiliang 阅读(1472) 评论(1)  编辑  收藏 所属分类: Java

FeedBack:
# re: 检查方法参数,平凡处的学问 2006-09-30 11:27 hsp
不同场合,对调用者的信任程度不同~
存在一种思想是,由调用者确保参数的正确性,当然这在某种场合下适用.
例如inbound  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: