是否有一个标准的java异常类,它的意思是;找不到对象";?

是否有一个标准的java异常类,它的意思是;找不到对象";?,java,exception,standard-library,Java,Exception,Standard Library,考虑以下一般形式的函数: Foo findFoo(Collection<Foo> foos, otherarguments) throws ObjectNotFoundException { for(Foo foo : foos){ if(/* foo meets some condition*/){ return foo; } } throw new ObjectNotFoundException();

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

Foo findFoo(Collection<Foo> foos, otherarguments)
throws ObjectNotFoundException {
    for(Foo foo : foos){
        if(/* foo meets some condition*/){
            return foo;
        }
    }
    throw new ObjectNotFoundException();
}
Foo findFoo(集合Foo,其他参数)
抛出ObjectNotFoundException{
for(Foo-Foo:foos){
如果(/*foo满足某些条件*/){
返回foo;
}
}
抛出新的ObjectNotFoundException();
}
例如,一个具体案例是:

User findUserByName(Collection<User> users, String name)
throws ObjectNotFoundException {
    for(User user : users){
        if(user.getName().equals(name)){
            return user;
        }
    }
    throw new ObjectNotFoundException();
}
User findUserByName(集合用户,字符串名称)
抛出ObjectNotFoundException{
for(用户:用户){
if(user.getName().equals(name)){
返回用户;
}
}
抛出新的ObjectNotFoundException();
}

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

这取决于您的方法记录的接口契约:

如果方法的文档说明
name
参数必须与现有用户的名称相对应,那么如果找不到该名称,则可以抛出
IllegalArgumentException
,因为这意味着调用方通过传递与用户不对应的名称违反了方法的要求

如果您的方法没有说明名称必须与现有用户对应,那么传递未知名称不是错误,您根本不应该抛出异常。在这种情况下,返回
null
是合适的


请注意,您的
findUserByName
方法基本上是在重新创建该方法,如果找不到指定的键,该方法将返回
null

illegalgumentException
有时在这里使用,但使用您自己的异常是完全可以的

顺便说一句,我建议使用一个映射,将
字符串名称
作为键,将
用户
作为值。这样就不需要在集合上进行迭代,并且可以防止集合中有两个同名的用户。如果您不想使用映射,那么至少要防止
NullPointerException
这样:

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);
}
User findUserByName(集合用户,字符串名称)抛出ObjectNotFoundException
{
if(name==null)
{
抛出新的IllegalArgumentException(“名称参数不能为null”);
}
如果(用户==null)
{
抛出新的IllegalArgumentException(“用户集合不得为空”);
}
for(用户:用户)
{
if(name.equals(user.getName()))
{
返回用户;
}
}
抛出新的ObjectNotFoundException(“无法找到名为:“+name”的用户);
}
您知道这里是否有可以使用的标准异常吗

可以使用一些例外情况(例如,
NoSuchElementException
IllegalArgumentException
),但答案实际上取决于您想要传达的语义:

  • NoSuchElementException
    通常在单步执行序列或枚举时使用,这里的内容是查找


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

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

(但不要试图使用它。那将是非常错误的;请阅读javadoc!)


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

对于Java8及以后的版本,返回
可选的
比返回
null
更干净



在这些方面,重要的是要超越教条,并根据实际的上下文要求做出决定。

对于Java 8,我建议在这个用例中使用可选的选项

Optional<User> findUserByName(Collection<User> users, String name){
    Optional<User> value = users
        .stream()
        .filter(a -> a.equals(name))
        .findFirst();
}
可选findUserByName(集合用户,字符串名称){
可选值=用户
.stream()
.filter(a->a.equals(名称))
.findFirst();
}

这也让调用者非常清楚,如果找不到该值,则可选值可以为空。如果你真的想抛出一个异常,你可以在Optional中使用
orelsetrows
来实现它。

IlleagalArgumentException
?为什么你坚持让JDK提供异常,而它是三行代码自己提供的呢?我不知道您还使用了哪些API;JPA提供了一个“NoResultException”例如,我会选择:
IllegalArgumentException
,正如文档中所说:
抛出以指示某个方法传递了非法或不适当的参数。
这实际上就是正在发生的情况。IMHO最好创建与方法/类/层/应用程序上下文相关的自定义异常,但是如果您坚持使用
NoSuchElementException
@Gimby,那么OP“坚持”JDK提供异常是在什么时候?OP陈述了一个偏好并提出了一个问题。此外,三行代码在适当记录时会变长。如果JDK已经提供了,为什么还要麻烦呢