2012-11-17 61 views
4

我有以下方法IndexOutOfBoundsException异常返回什么?

private ArrayList<User> allUsers = new ArrayList<User>(); 

public User getUser(int index) { 
    try { 
     return allUsers.get(index); 
    } 
    catch(IndexOutOfBoundsException e) { 
     // What should I return here?? Say that you want index 0 and no User 
     // exists in the ArrayList allUsers, what should I then return? The 
     // method needs a User to be returned 
    } 
} 

而且我不知道怎么在这里做,我敢肯定,这就是它的一个简单的办法,但我应该在catch块返回? Eclipse正在抱怨必须返回User

+8

只需返回空值即可。 – Doorknob

+4

或者没有发现异常 – Bohemian

+4

让异常通过; getUser方法的调用者有问题。 –

回答

3

如果没有用户发现我会抛出异常。该方法被调用时会捕获此异常。如果需要,您可以在此修改代码以使用自定义异常。喜欢的东西:

public User getUser(int index) throws IndexOutOfBoundsException { 
    if(index >= allUsers.size()){ 
     throw new IndexOutOfBoundsException("User doesn't exist"); 
    } 
    return allUsers.get(index); 
} 
+1

“IndexOutOfBoundsException”未被选中。你不需要声明它。 –

+0

这是真的,我把代码放在了他想要抛出一个自定义excepction而不是出界的地方,也许他想创建一个UserNotFoundException或者什么的,他会知道把它放在哪里。但是你的观察是非常重要的。 – alemangui

+2

@JanDvorak添加一个throws子句明确地表明这个方法将抛出IndexOutOfBoundsException;这不是必需的,但如果这实际上是其他用户的API,则可能会有所帮助。 –

11

问自己一个问题:“如果你想索引0并且没有用户存在,你应该返回什么?”并返回你回答的任何内容。

如果你没有答案,你应该重新抛出异常,或者不要抓住它。

需要注意的是很多时候,答案将返回null,如果是接受的行为要求一个不存在的用户。


边评论:它通常被认为是“好的做法”不依赖于捕捉异常,但首先测试错误条件。在你的情况下,你正在尝试get一个无效的对象索引,然后反应如果吸气剂爆炸。相反,我会建议首先测试index参数(确保它至少为零并且小于allUsers的长度),并且如果测试失败(返回null或抛出您自己的异常),则测试失败。

+1

+1,特别是对于这种情况下真正有用的所谓的“副评论”。 –

+0

+1;请注意,一些例外情况(扫描器 - > InputMismatchException)不能被阻止。 –

+0

@JanDvorak我不知道这个特定的例子,但那是当你*有*求助于捕捉抛出的异常。在这个特定的例子中,在绝大多数情况下,防止异常被抛在第一位(*但不一定100%万无一失,尽管如此)是相当微不足道的。 –

2

不要听Eclipse。

您有两种选择,根据具体情况,两种选择都可以是好还是不好。

  1. 您可以返回null
  2. 你可以重新抛出异常(或者说,甚至根本就没有抓到它),要求调用方法来处理它。

还有几个变化,但基本的选择是在上述两个之间:处理问题到位或委托任务给调用者。

仅凭这些代码就无法确定哪一个是正确的解决方案,只有您可以知道哪种情况更适合。

无论您选择哪种方式,最好手动检查索引(0<=index<allUsers.size()),而不要依赖RuntimeExceptions来获得正常的程序行为。

+0

Eclipse'抱怨',因为每条路径都需要返回一些东西。所以他应该听那个(否则它永远不会编译)。 –

+0

@MarkRotteveel OP写道:“Eclipse说一个用户必须返回”。这是公然不真实的,你也可以抛出一个异常。 – biziclop

+1

解释Eclipse(或编译器)试图传达什么可能会更好,而不是简单地说不听它。 –

2

假设index是用户输入,只需让IndexOutOfBoundsException传播并在可以显示错误消息的位置将它捕获得更远。

实际上,在尝试查找同样的事情之前,您可以先对allUsers.size()验证index。用户输入通常应在尽可能早的时候进行验证。

4

有很多可能性。其中一些取决于你的信仰。

  • ,因为传递的参数 无效可以抛出IllegalArgumentException。

  • 您可以抛出IndexOutOfBoundsException异常。

  • 如果你想确保客户端(此方法的调用者)必须采取 照顾它,你甚至可以申报检查的异常(定义 异常类扩展除外),因为 抛出:IllegalArgumentException和IndexOutOfBoundsException异常是运行时 异常,这意味着你不必明确地准备自己。

我平时检查,如果指数在范围内,如果没有返回null,因为它可以返回空值的Javadoc提及是否......

+1

+1,特别是因为我不得不对'取决于你的信仰'发笑:) –

15

我一般的看法是,你应该永远也赶不上的例外,你不知道如何处理。特别是在这种情况下,因为IndexOutOfBoundsExceptionRuntimeException,因此不需要被捕获 - 您可以让它沿着调用堆栈传播。调用者通过列表索引来请求一个对象,因此大概已经知道要索引哪个索引 - 然后,抛出或允许抛出的IndexOutOfBoundsException异常传播似乎是非常自然的。

唯一的另一个显而易见的选择是吞下异常和return null,但我真的不喜欢这样的方法来处理调用方的这种明显的错误,因为没有明显的返回值。你也可以返回一个特殊User实例(参照空对象模式),但即使这并不能免除责任的调用者来检查返回什么。取决于User的接口和实现,这种检查可能是微不足道的,但它仍然需要在某个地方完成。

如果你想明确的是,该方法可以抛出异常,只是这么说:

public User getUser(int index) throws IndexOutOfBoundsException { ... } 

或者像@Bela Vizer建议,把它包在一个IllegalArgumentException(这也是一个RuntimeException)。

以及由@lc.指出,这是更好,如果对象试图访问它之前存在先检查自己。处理你自己,你期望而不是依靠get()方法调用抛出异常错误的情况。但是,如果例如在检查和返回之间修改了集合,那么您应该仍然清楚这样一个事实,即方法可能会在处抛出这样的异常。使用多核CPU上的多线程软件,已知会发生陌生事物。

2

我会回来null,但是,如果你觉得你的应用程序可能会崩溃,因为这一点,你可以简单地返回一个“没有人”用户是这样的:

return new User("nobody", ...); 

并处理在功能之外的情况。

另一种方法是抛出异常外处理。

+7

不,只是 - **否**。如果你使用空对象模式,*至少*暴露一个公共的,只读的'NoSuchUser'实例,你返回并且可以进行比较。或者在某处公开一个公共方法来检查'User'实例是否是一个真正的用户。当你走的时候不要做一个。 –

1

您有几种选择:

  1. 返回null。如果用户可以合理地输入任何索引,请执行此操作。
  2. 不要捕捉异常。如果用户输入错误数据是完全意想不到的,换句话说,输入已被检查,所以这是造成这种情况的“编程错误”(或错误)。
  3. 抛出检查异常。如果您觉得呼叫代码可以并应该处理该问题,请执行此操作。
相关问题