是否有标准的 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
Is there a standard java exception class that means "The object was not found"?
提问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. NoSuchElementException
or IllegalArgumentException
) but the answer really depends on the semantics that you intend to convey:
有几个例外的是可以使用(例如NoSuchElementException
或IllegalArgumentException
),但答案实际上取决于你想要传达的语义:
NoSuchElementException
tends to be used when you are stepping through an sequence or enumeration, where what you have here is a lookup.IllegalArgumentException
tends 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 null
is that the caller needs to check for null
or risk unexpected NullPointerException
s. Indeed, I would argue that over-use of null
is 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 Optional
would 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 name
argument mustcorrespond to the name of an existing user, then it's appropriate to throw IllegalArgumentException
if 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 null
would be appropriate in this situation.
如果您的方法没有说明名称必须与现有用户相对应,则传递未知名称不是错误,您根本不应该抛出异常。null
在这种情况下,返回是合适的。
Note that your findUserByName
method is basically reinventing the Map.get
method, which returns null
if the specified key isn't found.
请注意,您的findUserByName
方法基本上是重新发明Map.get
方法,null
如果未找到指定的键,则返回该方法。
回答by Paul
IllegalArgumentException
is sometimes used here but using your own Exception is perfectly fine.
IllegalArgumentException
有时在这里使用,但使用您自己的 Exception 完全没问题。
As an aside I'd recommend using a Map with String name
as the key and User
as 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 NullPointerException
like 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 orElseThrows
in Optional to achieve it.
这也让调用者非常清楚,如果未找到值,则可选项可以为空。如果真的想抛出异常,可以使用orElseThrows
in Optional 来实现。