10.5 例子:Java子串方法
作为最后一个例子,考虑一下Java的String
类和它的substring
方法。给定一个字符串的两个索引,substring
返回从第一个索引给出的字符开始到第二个索引之前的字符结束的子串。然而,如果任何一个索引超出了字符串的范围,那么substring
就会抛出IndexOutOfBoundsException
。这个异常是不必要的,并且使这个方法的使用变得复杂。我经常发现自己遇到这样的情况:索引的一端或两端可能超出了字符串的范围,而我想提取字符串中所有与指定范围重叠的字符。不幸的是,这需要我检查前后两端的索引,并将它们向上取到零或向下取到字符串的末尾;本来只需要一行的方法调用现在变成了5-10行的代码。
如果Java的 substring
方法能自动进行这种调整,那么它将更容易使用,从而实现这样的API:“返回索引大于或等于beginIndex
且小于endIndex
的字符串的字符(如果有的话)”。这是一个简单而自然的API,它将IndexOutOfBoundsException
异常定义为不存在。现在,即使索引的一端或两端是负数,或者beginIndex
大于endIndex
,该方法的行为也被很好地定义了。这种方法简化了方法的API,同时增加了方法的功能,所以它使方法更深。许多其它语言都采取了无错误(error-free)的方法;例如,Python 对超出范围的列表切片返回一个空结果。
当我主张将错误定义为不存在时,人们有时会反驳说,抛出错误可以抓到bug;如果错误被定义为不存在,岂不是会导致软件的bug更多?也许这就是为什么Java开发者决定substring
应该抛出异常。有错误(error-ful)的方法可能会捕捉到一些bug,但也会增加复杂性,从而导致其他bug的出现。在有错误的方法中,开发者必须编写额外的代码来避免或忽略错误,这就增加了出现错误的可能性;或者,他们可能忘记编写额外的代码,在这种情况下,运行时可能会抛出意想不到的错误。相比之下,将错误定义为不存在可以简化API,同时减少了必须编写的代码量。
总的来说,减少错误的最好方法是使软件更简单。
Last updated