避免索引超出范围的exception

我正在使用数组列表来存储有关在屏幕上移动对象的数据。 我怀疑这是因为我的渲染器和我的逻辑在不同的线程上运行,但有时当从列表中删除数据时,我得到一个indexOutOfBoundsException。 我已经采取了我能想到的所有步骤来避免这种情况,包括try / catch,但有时会发生exception。 这是我的渲染器线程的一部分,似乎导致exception。

public void drawMobs(GL10 gl) { boolean playing = MyLaunchActivity.getPlaying(); if(playing == true){ try{ ArrayList mobDat = Play.getMobDat(); while (currentLoadSpace < mobDat.size()){ if(!mobDat.isEmpty() || currentLoadSpace < mobDat.size()){ loadObject = mobDat.get(currentLoadSpace); float loadCoordX = Float.parseFloat(mobDat.get(currentLoadSpace + 2)); float loadCoordY = Float.parseFloat(mobDat.get(currentLoadSpace + 3)); /*some rendering*/ currentLoadSpace+=4; } } }catch( ArrayIndexOutOfBoundsException e){ Log.d(TAG, "caught");} currentLoadSpace = 0; }} 

你可以看到我尝试过一些东西,但错误仍然存​​在。 这是错误日志

 01-02 14:02:42.650: E/AndroidRuntime(6947): FATAL EXCEPTION: GLThread 10 01-02 14:02:42.650: E/AndroidRuntime(6947): java.lang.IndexOutOfBoundsException: Invalid index 23, size is 20 01-02 14:02:42.650: E/AndroidRuntime(6947): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) 01-02 14:02:42.650: E/AndroidRuntime(6947): at java.util.ArrayList.get(ArrayList.java:308) 01-02 14:02:42.650: E/AndroidRuntime(6947): at basicmelon.games.agameofsorts.LoadLevel.drawMobs(LoadLevel.java:530) 01-02 14:02:42.650: E/AndroidRuntime(6947): at basicmelon.games.agameofsorts.MyGLSurfaceRenderer.onDrawFrame(MyGLSurfaceRenderer.java:82) 01-02 14:02:42.650: E/AndroidRuntime(6947): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1429) 01-02 14:02:42.650: E/AndroidRuntime(6947): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1184) 

一种可能的解决方案是:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

如果这不是一个选项,您可以使用synchronized(yourList){}来阻止concurent修改。

您的代码不一致且相当错误。 例如,为什么你测试两次相同的条件? ( currentLoadSpace < mobDat.size()

其次,您的错误来自:

 mobDat.get(currentLoadSpace + 3) 

mobDat只包含21个元素时,你正在搜索23的索引。 所以你应该检查以下几行实际上是否小于mobDat.size()

 currentLoadSpace + 2 

 currentLoadSpace + 3 

我认为你必须同步对ArrayList的访问。 ArrayList不是线程安全的。 捕获IndexOutOfBoundsException是糟糕的设计。 您的代码应该避免此exception。

您需要检查arraylist大小。 删除的位置不应大于列表的大小

你需要做如下的事情

 void avoidArrayIndexOutOfBounds(int position, ArrayList listOfdata){ if(position>(listOfdata.size()-1)){ position = listOfdata.size()-1; } } 

另请注意,您正在检查currentLoadSpace是否小于mobDat.size(),但您正在尝试从currentLoadSpace + 3进行检索(就这段代码而言,可能会超出范围)。

我知道已经有了答案,但尝试只是捕获IndexOutOfBoundsException而不是ArrayIndexOutOfBoundsException

我建议这是因为你正在捕获Arrayexception并仍然获得标准的Indexexception。 这很可能是由于Index是一个“更高/更低”(但是你想看到它)exception而不是Arrayexception。 这意味着您确实捕获了Arrayexception,但除此之外,仍然会抛出Index 1。