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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24760314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:43:23  来源:igfitidea点击:

Is there a standard java exception class that means "The object was not found"?

javaexceptionstandard-library

提问by abl

Consider a function of the following general form:

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

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

A concrete case, for example, would be:

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

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

These functions throw an exception if the object is not found. I can create a custom exception class for this purpose (in the examples, ObjectNotFoundException) but I would prefer to use an existing class. However, I could not find any exception class with this meaning in the standard java library. Do you know if there is a standard exception that can be used here?

如果未找到对象,这些函数将抛出异常。我可以为此目的创建自定义异常类(在示例中ObjectNotFoundException),但我更愿意使用现有类。但是,我在标准 Java 库中找不到任何具有此含义的异常类。不知道这里有没有标准异常可以用?

采纳答案by Stephen C

Do you know if there is a standard exception that can be used here?

不知道这里有没有标准异常可以用?

There are a couple of exceptions that couldbe used (e.g. NoSuchElementExceptionor IllegalArgumentException) but the answer really depends on the semantics that you intend to convey:

有几个例外的是可以使用(例如NoSuchElementExceptionIllegalArgumentException),但答案实际上取决于你想要传达的语义:

  • NoSuchElementExceptiontends to be used when you are stepping through an sequence or enumeration, where what you have here is a lookup.

  • IllegalArgumentExceptiontends to imply that the argument is in error, but in this case, it could be that the assumptions of the caller are incorrect, or something that is specific to the application logic.

  • A custom exception allows you to say (in the javadocs) exactly what the exception means. You can also declare it to be checked... if that it appropriate.

  • NoSuchElementException当您单步执行序列或枚举时,通常会使用它,您在这里进行的是查找。

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

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

(But don't be tempted to use UnknownUserException. That would be horribly wrong; read the javadoc!)

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



It is also worth considering returning null, especially if lookup failure is likely to be a fairly common (non-exceptional) event in your application. However, the downside of returning nullis that the caller needs to check for nullor risk unexpected NullPointerExceptions. Indeed, I would argue that over-use of nullis worse than over-use of exceptions. The former can result in unreliable applications, whereas the latter is "only" bad for performance.

还值得考虑 return null,特别是如果查找失败可能是您的应用程序中相当常见(非异常)的事件。 然而,返回的缺点null是调用者需要检查null或冒意外NullPointerException的风险。事实上,我认为过度使用null比过度使用异常更糟糕。前者会导致应用程序不可靠,而后者“仅”对性能不利。

For Java 8 and onwards, returning an Optionalwould be a cleaner choice than returning a null.

对于 Java 8 及更高版本,返回 anOptional将是比返回 a 更简洁的选择null



In these things, it is important to look beyond the dogmas, and make up your mind based on what the actual context requires.

在这些事情上,重要的是要超越教条,并根据实际情况的需要下定决心。

回答by MGorgon

Exceptions are created to mark exceptional behaviour. In my opinion, object not found situation is not exceptional. I would rewrite your method to return null, if user is not found.

创建异常以标记异常行为。在我看来,找不到对象的情况并不例外。如果找不到用户,我会重写您的方法以返回 null。

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

This is standard behaviour for many Java Collections. For example, http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object)will return null, when no entry with specified key is in the map.

这是许多 Java 集合的标准行为。例如,http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object)将返回 null,当指定键的条目不在地图。

You should avoid relying on exceptions in your programms logic.

您应该避免依赖程序逻辑中的异常。

回答by Wyzard

It depends on your method's documented interface contract:

这取决于您的方法记录的接口合同:

If your method's documentation states that the nameargument mustcorrespond to the name of an existing user, then it's appropriate to throw IllegalArgumentExceptionif the name isn't found, because it means the caller violated the method's requirements by passing a name that doesn't correspond to a user.

如果您的方法的文档规定name参数必须与现有用户的名称相对应,那么IllegalArgumentException如果找不到名称则抛出是合适的,因为这意味着调用者通过传递不对应的名称违反了方法的要求一个用户。

If your method doesn't say that the name must correspond to an existing user, then passing an unknown name is not an error and you shouldn't throw an exception at all. Returning nullwould be appropriate in this situation.

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

Note that your findUserByNamemethod is basically reinventing the Map.getmethod, which returns nullif the specified key isn't found.

请注意,您的findUserByName方法基本上是重新发明Map.get方法,null如果未找到指定的键,则返回该方法。

回答by Paul

IllegalArgumentExceptionis sometimes used here but using your own Exception is perfectly fine.

IllegalArgumentException有时在这里使用,但使用您自己的 Exception 完全没问题。

As an aside I'd recommend using a Map with String nameas the key and Useras the value. Iterating over the collection would then be unnecessary and it would prevent having two users with the same name in the collection. If you don't want to use a Map then at least defend against NullPointerExceptionlike so:

顺便说一句,我建议使用 MapString name作为键和User值。这样就没有必要对集合进行迭代,这将防止集合中有两个具有相同名称的用户。如果您不想使用地图,那么至少要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);
}

回答by Alastor Moody

With Java 8, I would recommend using an Optional for this use case.

对于 Java 8,我建议在此用例中使用 Optional。

Optional<User> findUserByName(Collection<User> users, String name){
    Optional<User> value = users
        .stream()
        .filter(a -> a.equals(name))
        .findFirst();
}

This also makes it very clear to the caller that the optional can be empty if the value is not found. If you really want to throw an exception, you can use orElseThrowsin Optional to achieve it.

这也让调用者非常清楚,如果未找到值,则可选项可以为空。如果真的想抛出异常,可以使用orElseThrowsin Optional 来实现。