我有一个方法getUser
,它从数据库中检索用户。该方法要求您验证用户是否确实存在(通过userExists(String username)
方法。
如果调用getUser
方法并且用户不存在,我想抛出一个未经检查的异常,但哪个异常最合适?我想过IllegalArgumentException
,但感觉不完全正确,因为在某些情况下某些输入可能没问题,但在其他情况下则不然 - 它们并非严格“非法”。有什么建议吗?
答案 0 :(得分:13)
对我来说IllegalArgumentException意味着参数是非法的并且总是非法的。我将使用的异常是IllegalStateException来说明检查用户无效的对象的状态。
但是,您可能有一个特定的例外,您可以创建自己的例外。
public class UsernameNotCheckedException extends IllegalStateException {
public UsernameNotCheckedException(String message) {
super(message);
}
}
这可能会使调试变得更容易。
NumberFormatException
是IllegalArgumentException
的子类。如果您尝试解析数字12QW4
,它将为您提供NumberFormatException
,并且您无法做任何事情以使其成为有效参数。即它与任何事物的状态无关。
IllegalStateException
州的Javadoc。
表示在非法或不适当的时间调用了某个方法。换句话说,Java环境或Java应用程序未处于所请求操作的适当状态。
答案 1 :(得分:3)
IllegalStateException
不是正确的选择。 IllegalStateException
指的是已调用其方法的对象的状态 - 即this
的状态不正确,因为它已被调用。在您的情况下this
(即数据库服务器)很好,用户是“不正确的”。
IllegalArgumentException
是正确的选择 - 用户不正确,而不是服务器。
另一个有效选项是抛出您自己的特定于域的异常,例如UnknownUserException
,但如果这种情况“罕见”或意外且无法恢复,则可以坚持使用IllegalArgumentException
答案 2 :(得分:1)
我不会抛出任何异常,只返回null
。或者我会抛出一个名为UserDoesNotExistException
的函数异常。
这是我的推理:当用户调用一个在给定对象状态时被禁止的方法时,使用IllegalStateException
。这里,不是导致异常的对象的状态。事实是用户不存在于数据库中。
您可能认为用户之前应该调用userExists
,并且此方法甚至可以使用实例字段记住它已被调用(使用此参数),以便{{1} IllegalStateException
可以抛出它,甚至不用去数据库。
但问题是,之前调用getUser
可能不会添加任何内容:它将执行查询以检查用户是否存在,然后userExists
将执行第二个查询,而不是保证找到用户,因为另一个交易可能已将其删除。