我正在制作一个包含一些解析字符串日期和时间的方法的库。当字符串参数不可解析时,我很难决定这些方法应该抛出什么异常。我正在考虑几种选择:
1. java.lang.IllegalArgumentException
- 一个无效的字符串显然是一个非法的参数,但是,对我来说,IllegalArgumentException
通常意味着编程错误,很少有人想做显式 try catch
对于一个。我认为字符串解析通常用于外部输入,并且更像是一种值得特殊对待的特殊情况。例如,如果您有一大块代码来解析用户输入并对其进行其他操作,您可能希望将该代码包装在 try catch 块中,以便您可以处理用户输入包含无效字符串的情况。但 catch IllegalArgumentException
对于查明无效的用户输入来说不是很好,因为很可能在您的代码中有多个地方可以抛出它(不仅仅是用户输入解析)。
2. java.lang.NumberFormatException
- 它是由 Integer.parseInt(String)
抛出的以及 java.lang
中的其他类似解析方法.因此,大多数 Java 开发人员都熟悉它是在您尝试解析可能有效或无效的字符串(例如用户输入)时捕获的异常。但它的名字中有“数字”,所以我不确定它是否真的适合日期和时间等在某种意义上是数字的东西,但在我看来在概念上是不同的。如果它被称为“FormatException”...
3. java.text.ParseException
- 不是真正的选择,因为它被选中。我想取消检查这一点。
4. 自定义异常 - 这解决了 IllegalArgumentException
的缺点和 NumberFormatException
,它可以扩展 IllegalArgumentException
也。但我认为向库添加异常不是一个好主意,除非确实需要它们。引用乔什·布洛赫 (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 类(class))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
虽然这不是官方的教条,但我认为这是一种很好的做法。所有这三个都是简单和自我描述的。
关于Java API 设计 : NumberFormatException for Method that Parses a Semi-Numeric String?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5676245/