【问题标题】:How Should I Handle This IndexOutOfBounds Exception?我应该如何处理这个 IndexOutOfBounds 异常?
【发布时间】:2014-11-10 11:28:20
【问题描述】:

我在下面有一些代码,在一些非常模糊的情况下,fromIndex 变量设置为 -1:

int fromIndex = 0;
if (newCurrentPeriod != null) {
    // Guard in case we are rolling back to before the start of the event.
    fromIndex = allPeriods.indexOf(newCurrentPeriod);
}  
for (Period resetPeriod : allPeriods.subList(fromIndex, toIndex)) {
    ...
}

目前,如果fromIndex is -1,则ArrayList class will throw an IndexOutOfBounds Exception within the sublistRangeCheck method

我的查询:

我应该如何在我们的代码中最好地处理这个异常?我应该用 try catch 包围它,打印堆栈跟踪并记录一些附加信息以进行调试吗?我是否应该在执行 for 循环之前防御性地检查 fromPeriod 是否 >= 0,如果没有记录一些信息?

您将如何/在您的代码中处理此类场景的最佳做法是什么?

提前致谢。

【问题讨论】:

  • 如果 fromIndex 变为 -1,你想要做什么默认值?您应该默认为 0 还是从那里返回等?

标签: java exception arraylist error-handling indexoutofboundsexception


【解决方案1】:

理想情况下捕获 IndexOutOfBounds(RuntimeException) 不是一个好习惯。

运行时异常是一种可能被程序员避免的异常。

运行时异常应仅在完整操作结束时捕获,仅用于向用户显示已发生错误的消息。

此外,在编译时不会识别运行时异常,如果您可以通过一个小检查(如 NullPointer 的空检查,IndexOutofBounds 的索引检查)来识别异常的概率,这是减少JVM 上的开销。

添加对 fromIndex == -1 的检查会是更好的方法,并记录发生迭代的详细信息。

【讨论】:

  • 您能否详细说明为什么这是不好的做法?
【解决方案2】:

对于那些晦涩难懂的场景,我更喜欢在进入方法之前进行检查。

int fromIndex = 0;
    if (newCurrentPeriod != null) {
        // Guard in case we are rolling back to before the start of the event.
        fromIndex = allPeriods.indexOf(newCurrentPeriod);
    }  
if (fromIndex>=0)
    for (Period resetPeriod : allPeriods.subList(fromIndex, toIndex)) {
        ...
    }
else syso("print something");

【讨论】:

    【解决方案3】:

    indexOf 是 List 接口的一部分,文档中的定义说:

    https://docs.oracle.com/javase/7/docs/api/java/util/List.html#indexOf(java.lang.Object)

    返回:指定元素在中第一次出现的索引 此列表,如果此列表不包含该元素,则为 -1

    更确切地说:

    更正式地说,返回满足 (o==null ? get(i)==null : o.equals(get(i))),如果没有这样的索引,则为 -1。

    这意味着当您获得 -1 的索引时,您要查找的对象在列表中不存在。

    您是否在对象中实现了自定义“equals”方法?如果没有,则 List Impl。正在使用对象的实例 id 来匹配它们,这意味着包含相同数据的该对象的两个实例仍然不同,因为它们不是同一个实例!

    因此,如果您确定要查找的对象在列表中,请检查您的“equals”方法或实施一个根据输入而不是实例比较对象的方法。

    如果搜索到的对象可能不在列表中,那么您只需处理不需要获取子列表的情况。

    if (formIndex >= 0) {
            for (Period resetPeriod : allPeriods.subList(fromIndex, toIndex)) {
                ...
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-09-01
      • 2021-04-01
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多