何时抛出IllegalStateException与IllegalArgumentException?
让我们从Javadocs开始:
IllegalStateException异常
表示某个方法在非法或不适当的时间被调用。 换句话说,对于请求的操作,Java环境或Java应用程序不处于适当的状态。
抛出:IllegalArgumentException
抛出以表明某个方法已通过非法或不恰当的参数。
上述问题在于它们非常黑白。 考虑一个方法是解析调用者提供的文件的用例。 该文件存在,可读,并且格式正确。 但是,文件中的某些内容不符合业务规则。 在这种情况下抛出什么适当的异常 - IllegalStateException
或IllegalArgumentException
?
查看各种提供断言的库,如番石榴前提条件或春天断言,似乎没有共识。 这里和这里有一些很好的讨论,但是没有一个能够为我上面提到的常见用例提供确凿的答案。
免责声明:我知道我没有展示一些代码,但我认为这是一个具体而实用的问题,需要考虑良好的API设计。 让我们假装一段时间,我们已经回到了堆叠式的好时光,当时人们很乐意讨论务实的问题,而不是低估任何看起来不像家庭作业的东西。
换句话说:
IllegalArgumentException在类型被接受但不是值的情况下抛出,例如期待正数并给出负数。
IllegalStateException在应用程序不应该调用时调用,例如从死线程中调用方法。
我看不出他们如何混合。 在你关于带有问题的文件的问题中,我认为抛出一个ParseException或一个IOException会更合适。
其他答案突出显示何时使用IllegalArgumentException
或IllegalStateException
。 但在我看来(注:基于意见),这些例外不应该用在你的用例中。
总结:某些文件包含有效格式的数据,已成功加载到应用程序中,但某些值不符合业务规则(注意:没有IO操作失败,格式有效=>既不应使用IOException
也不应使用ParseException
,它们表示IO操作失败或格式无效)。
为什么你不应该使用IllegalArgumentException
?
抛出此异常是为了表明某个方法已通过非法或不恰当的参数。 您可以争辩说您有一种验证文件的方法,并且此文件中字段的值或多个字段的值的组合是非法的或不符合您的业务规则。 Yepp,指向你。 但是,如果你抛出IllegalArgumentException
在这种情况下,你不能单独IllegalArgumentException
■通过其他库(或标准库或您自己的代码别处)引起的,该IllegalArgumentException
是从你们的验证这很容易地表示业务规则冲突(当然,你可以继承IAE并在调用方法中捕获它)。
你为什么要分开这些例外? 使用案例:业务规则违规应呈现给用户,以便他可以更改他的不合规输入。 其他IAE或通用的任何未捕获的运行时异常表明请求在服务器上失败。 在这些情况下,您必须向客户发送不同的回复。
您可以用类似的方式争论为什么不应该使用IllegalStateException
来指示业务规则违规。 那么,你的用例应该用什么呢? 这很大程度上取决于您的应用程序的规模。 一些RuntimeException
自定义子类可以为小应用程序执行作业。 对于较大的应用程序,像“javax.validation”这样的验证库值得一试。
IllegalStateException
是用于编码错误,而不是输入错误。 这是因为当一个类的不变量被违反时,或者当一个对象处于错误状态时调用一个方法。 示例使用封闭的资源,或关闭资源两次。
IllegalArgumentException
是每个方法API的参数具有无效值时。 只允许正数时传递-1。
在这种情况下,这两种情况都不适用 我会创建一个IOException
的子类,因为输入文件中存在错误。
上一篇: When to throw IllegalStateException vs IllegalArgumentException?