抛出异常还是预防异常?

3
问题是是否应该抛出异常或预防它发生。 这是一个游戏项目。
IndexOutOfBoundsException与编码绕过它。
我有一个List。
private Attribute<List> attributes;

通过索引获取项目的方法。
public Attribute getAttribute (int index) {
    if (index < 0 || index >= attributes.size())
        index = 0;

    return attributes.get(index);
}

在这种情况下,我将默认使用列表的第一个元素。

1
想象一下,当你作为用户玩游戏,选择一个选项时,突然出现了这样奇怪的消息:IndexOutOfBoundsException when choosing weapon. Please report to game admins.永远不会再玩这样的游戏了。 - Luiggi Mendoza
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Emz
如果你编写了该方法并知道在特定情况下它可能会抛出此异常,为什么要编写错误使用该方法的代码呢?如果程序忽略错误而突然表现不良,用户将不喜欢你的游戏。而错误是发现漏洞的最佳途径。传递超出边界的索引显然是一个漏洞。 - zapl
2
@LuiggiMendoza 这并不意味着不应该抛出任何异常,而是意味着调用代码应该以这样的方式编写,使得索引始终是有效值。 - assylias
6
如果getAttribute可能被调用时传入的index不在0和attributes.size()之间,则说明您的代码中存在其他错误需要修复。在此争论是否应该在此处抛出异常有点毫无意义。 - Dawood ibn Kareem
显示剩余4条评论
3个回答

8
快速失败通常是一个好的想法:如果将-1的索引传递给该方法,则很可能意味着调用该方法的代码存在错误。如果您静默地使用index = 0,(a) 调用代码可能无法收到预期的结果,(b) 直到修复变得非常混乱之前,您可能都没有注意到该错误。因此,我会简单地使用:
public Attribute getAttribute (int index) {
    return attributes.get(index);
}

如果需要,它将抛出一个异常。如果调用此方法的代码没有错误,那么这个异常就不应该被抛出。


一个调试输出会保护我免受它的影响吗?就像@Luiggi提到的,作为玩家体验这种错误可能有点痛苦。 - Emz
@Emz 如果你想通过索引获取属性,那可能意味着你知道有多少可用的属性,所以 Luiggi 提到的情况不应该发生。如果你提供更多上下文,我们可以给出更具体的答案。 - assylias
很遗憾,我目前没有更多的上下文信息。我正在学习Java课程,他们提到始终要注意最坏情况的处理非常重要。(这个项目与该课程无直接关系。) - Emz
1
无论哪种方式都可以,但是使用@assylias所展示的方法,允许Exception被抛出将会在调试时节省程序员的时间和精力。编写代码以处理所有可能的异常情况也会更加耗时。 - Drew Kennedy

4
在这种情况下,假设索引存在并且是第一个元素相同的元素是令人困惑的,并且可能导致微妙的错误。
在这里,如果索引超出范围,我会抛出IndexOutOfBoundsException。请注意,调用此代码的其他代码必须准备好捕获此异常并适当处理它。

1
答案高度情境化。通常情况下,您希望尽可能优雅地处理异常。也就是说,在可能的情况下尝试解决/忽略它们。IndexOutOfBoundsException往往是这种情况不可能实现的一个例子。
由于异常而出现硬性中断是最后的手段。只有在程序无法继续时才能这样做。
此问题的答案有很好的帖子。 何时抛出异常?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接