【问题标题】:Java IndexOutOfBoundsExceptionJava IndexOutOfBoundsException
【发布时间】:2012-12-31 15:23:09
【问题描述】:

我创建了一个小安卓游戏,但出现了奇怪的错误。

这里是日志:

    12-31 16:10:22.407: E/AndroidRuntime(12824): FATAL EXCEPTION: Thread-1461
    12-31 16:10:22.407: E/AndroidRuntime(12824): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 0
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at java.util.ArrayList.get(ArrayList.java:304)
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at **.***.****.GameScreen.updatePaused(GameScreen.java:91)
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at **.***.****.GameScreen.update(GameScreen.java:43)
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at **.***.****.framework.impl.AndroidFastRenderView.run(AndroidFastRenderView.java:39)
    12-31 16:10:22.407: E/AndroidRuntime(12824):    at java.lang.Thread.run(Thread.java:856)

这是执行的部分代码:

    int len = touchEvents.size();
    for(int i = 0; i < len; i++) {
        TouchEvent event = touchEvents.get(i); ->>> this line
    .
    .
    .

怎么了?

【问题讨论】:

  • 你的代码是多线程的吗?如果是这样,touchEvents 是否有可能在另一个线程中被修改?
  • 您是否在迭代 touchEvents 时删除了元素?
  • 只测试'len'的值是否在记录器中返回一些值?
  • 正如上面所说的 jeet 使用 Eclipse 调试器或类似的东西来遍历前面的每一行,看看它是如何变化的,很难从你发布的代码中分辨出来
  • 它只是崩溃的事实有时听起来就像是由多线程引起的竞争条件。您绝对确定只有一个线程曾经触及该字段吗?

标签: java android indexing bounds out


【解决方案1】:

如果您遇到线程问题,您必须在像这样循环之前在集合上同步

synchronize(touchEvents) {
    for(TouchEvent event : touchEvents) {
        //do whatever you want with events
    }
}

或者,您可以制作集合的本地副本并在其上循环,如果在您处理副本时处理集合中的事件仍然有效的话。

【讨论】:

  • 我认为复制它是更优雅的方式。如果日志很快没有帮助,我会这样做。
【解决方案2】:

最安全的方法肯定是像这样使用增强的 for 循环

for(TouchEvent event : touchEvents) {
    //do whatever you want with events
}

【讨论】:

  • 如果touchEvents在迭代过程中以任何方式被修改,这仍然会抛出一个ConcurrentModificationException。它实际上并不能解决问题,也不是“更安全”。
  • 没错,但它仍然更安全,因为您可以避免像touchEvents.size() - 1这样的愚蠢错误
  • 同意。此外,更改集合类型更容易,因为增强的 for 循环适用于所有 Iterables。
  • 创建 touchEvents 列表的副本并像上面一样在 for-each 中使用它?
【解决方案3】:

您应该始终检查 NULL。

int len = touchEvents != null ? touchEvents.size() : 0
for(int i = 0; i < len; i++)
  TouchEvent event = touchEvents.get(i);

【讨论】:

  • 也可以这样。谢谢!
猜你喜欢
  • 2013-09-30
  • 2016-11-15
  • 2016-03-22
  • 2019-08-11
  • 1970-01-01
  • 1970-01-01
  • 2018-12-03
  • 2012-08-15
  • 1970-01-01
相关资源
最近更新 更多