我正在制作一个包含一些用于解析字符串日期和时间的方法的库。我很难确定当字符串参数不可解析时那些方法应该抛出什么异常。我正在考虑几种选择:
1. java.lang.IllegalArgumentException
-无效的字符串显然是非法参数,但是,对我来说,IllegalArgumentException
通常意味着编程错误,很少要为一个字符串执行显式的try catch
。我认为字符串解析通常用于外部输入,而更多是特殊情况,值得特殊对待。例如,如果您有一大段代码可以解析用户输入并对其进行了其他处理,则可能需要将该代码包装在try catch块中,以便处理用户输入包含无效字符串的情况。但是捕获IllegalArgumentException
并不是找出无效用户输入的好方法,因为很可能在代码中可能会抛出多个位置(而不仅仅是用户输入解析)。
2. java.lang.NumberFormatException
-它由Integer.parseInt(String)
和java.lang
中的其他类似解析方法抛出。因此,大多数Java开发人员都熟悉它是当您尝试解析可能有效或无效的字符串(例如用户输入)时捕获的异常。但是它的名称中带有“数字”,所以我不确定它是否真的适合日期和时间之类的东西,从某种意义上讲,它们是数字,但在我看来却是概念上的不同。如果只叫“FormatException” ...
3. java.text.ParseException
-并非真正的选项,因为已选中。我要对此取消检查。
4.定制异常-绕过了IllegalArgumentException
和NumberFormatException
的缺点,它也可以扩展IllegalArgumentException
。但是我认为除非确实需要异常(exception),否则将异常(exception)添加到库中不是一个好主意。引用Josh Bloch,"If in doubt, leave it out"。 (对于我来说,对于解析日期和时间的程序包来说,很难这样的异常命名:“DateFormatException”,“TimeFormatException”,“CalendricalFormatException”(例如JSR 310)-当应用于方法时,对我来说似乎都不理想解析日期,时间,日期时间等。我认为,如果一个包只用于识别无法解析的字符串,那么在一个包中创建多个异常将是很愚蠢的。)
那么,您认为哪种选择最有意义?
注意:我有充分的理由不想使用java.util.Date或Joda Time或JSR 310,因此无需提出建议。另外,我认为将这个问题保持在一般范围内会很好,因为这肯定是其他设计API的人都在苦苦挣扎的问题。日期和时间也可以是IP地址,URL或具有需要解析的字符串格式的任何其他类型的信息。
其他图书馆设置的先例
我发现了一些例子:java.sql.Timestamp.valueOf(String) throws IllegalArgumentException
java.util.Date.parse(String) throws IllegalArgumentException
(不建议使用的方法,没有声明异常,但是您可以在源代码中看到它)java.util.UUID.fromString(String) throws IllegalArgumentException
org.apache.axis.types.Time(String) throws NumberFormatException
(也是Apache Axis中的Day类)org.apache.tools.ant.util.DeweyDecimal(String) throws NumberFormatException
com.google.gdata.data.DateTime.parseDateTime(String) throws NumberFormatException
java.lang.Package.isCompatibleWith(String versionString) throws NumberFormatException
(在Java 7中,它采用带点的字符串版本号-在某种意义上类似于日期或时间)
我确定有很多使用自定义异常的软件包,因此我怀疑给出这些示例是否有意义。
最佳答案
我本来建议将 IllegalFormatException
作为基类(它继承自IllegalArgumentException
,但是不幸的是,唯一的构造方法是受程序包保护的,因此我可能会使用
的
IllegalArgumentException
小型API(一些方法)IllegalArgumentException
继承的类层次结构。 无论如何,我都将
IllegalArgumentException
用作基类。在我以前的项目之一中,指导原则是仅抛出从继承的RuntimeExceptions。
IllegalStateException
IllegalArgumentException
UnsupportedOperationException
尽管这不是官方的教条,但我认为这是一种很好的做法。所有这三个都是简单和自我描述的。