是否有标准的java异常类表示“未找到对象”?

2022-08-31 10:35:31

请考虑以下一般形式的函数:

Foo findFoo(Collection<Foo> foos, otherarguments)
throws ObjectNotFoundException {
    for(Foo foo : foos){
        if(/* foo meets some condition*/){
            return foo;
        }
    }
    throw new ObjectNotFoundException();
}

例如,一个具体的例子是:

User findUserByName(Collection<User> users, String name)
throws ObjectNotFoundException {
    for(User user : users){
        if(user.getName().equals(name)){
            return user;
        }
    }
    throw new ObjectNotFoundException();
}

如果未找到对象,这些函数将引发异常。我可以为此目的创建自定义异常类(在示例中),但我更喜欢使用现有类。但是,我在标准java库中找不到任何具有此含义的异常类。您知道是否有可以在此处使用的标准例外吗?ObjectNotFoundException


答案 1

您知道是否有可以在此处使用的标准例外吗?

有几个例外可以使用(例如 或),但答案实际上取决于您打算传达的语义:NoSuchElementExceptionIllegalArgumentException

  • NoSuchElementException倾向于在单步执行序列或枚举时使用,其中您在此处具有的是查找。

  • IllegalArgumentException倾向于暗示参数是错误的,但在这种情况下,可能是调用方的假设不正确,或者特定于应用程序逻辑。

  • 自定义异常允许您(在javadocs中)确切地说出异常的含义。您也可以声明要检查它...如果合适的话。

(但不要试图使用UnknownUserException。那将是可怕的错误。阅读 javadoc!


还值得考虑返回 ,尤其是在应用程序中查找失败可能是相当常见(非异常)事件的情况下。但是,返回的缺点是调用方需要检查或冒意外的风险。事实上,我认为过度使用比过度使用例外更糟糕。前者可能导致不可靠的应用程序,而后者“仅”对性能不利。nullnullnullNullPointerExceptionnull

对于 Java 8 及更高版本,返回 a 将比返回 .Optionalnull


在这些事情中,重要的是要超越教条,并根据实际背景的要求做出决定。


答案 2

IllegalArgumentException有时在这里使用,但使用你自己的异常是完全可以的。

顺便说一句,我建议使用地图作为键和值。然后,迭代集合将是不必要的,并且它将防止在集合中有两个具有相同名称的用户。如果你不想使用地图,那么至少要防御这样的情况:String nameUserNullPointerException

User findUserByName(Collection<User> users, String name) throws ObjectNotFoundException
{
  if (name == null)
  {
    throw new IllegalArgumentException("name parameter must not be null");
  }
  if (users == null)
  {
    throw new IllegalArgumentException("Collection of users must not be null");
  }
  for(User user : users)
  {
    if(name.equals(user.getName()))
    {
      return user;
    }
  }
  throw new ObjectNotFoundException("Unable to locate user with name: " + name);
}