[英]Java - Index Out Of Bounds Exception: Index: 1, Size: 2
在某些Java项目上工作时,我遇到了这个奇怪的错误:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 2
怎么会有索引超出范围异常? 索引1表示它试图获取第二个元素,大小2表示有2个元素,所以应该没有问题,不是吗?
语境:
我有以下功能:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
现在的问题是,我在该行得到了一个空指针异常:
agentsCount += cellsWithAgents.get(i).howManyAgents();
我想调试代码,但是在程序运行时会多次调用此函数,并且空指针异常会在不同的时间点出现(5分钟后的1分钟后为10秒)。 因此,我尝试提出一种在单元格为null时具有e断点的方法,因此我想出了以下代码:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
int pass;
if (null == cellsWithAgents.get(i))
pass = 1; // breakpoint here
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
当然,这不是最好的方法。 最合乎逻辑的方法是,用try / catch包围代码,然后在其中放置断点。 关键是上面的代码不起作用。 它并没有在断点处停止,而是将索引超出了该行的界限异常:
if (null == cellsWithAgents.get(i))
为什么? 如果索引显然在边界内,怎么可能将索引抛出边界异常?
编辑:更改了复制代码时的错误
更新:我试图看看为什么空指针异常会出现try / catch并在其中放置一个断点。 似乎cellsWithAgents有时包含null。 这很可能是由于@rlinden指出的并发性。
关于并发:有些单元格可以包含代理。 可以在单元之间移动的代理数量不固定。 有一个特殊的座席试图计算有多少座席(使用此功能)。 因此,只有一个代理(线程)可以使用此功能,但是多个代理可以修改单元格(从而使getNonEmptyCells()和howManyAgents()结果混乱)。
但是,如何才能使索引超出大小2和索引1的范围? 因为并发,所以不可能吗? 因为只有该线程才能更改列表cellsWithAgents。 因此,即使列表中的元素之一变为空,列表仍然包含该数量的指针,因此列表的大小无法更改。 还是可以以某种我想念的方式? 以及如何解释堆栈跟踪打印索引:1大小:2?
新思路
尝试更改循环,看看错误是否仍然存在:
int agentsCount = 0;
for(Cell cell : getNonEmptyCells()) {
if(cell != null) {
agentsCount += cell.howManyAgents();
} else {
System.out.println("Found a null cell");
}
}
我想看一下getNonEmptyCells()
方法的代码。 如果您的程序实际上是多线程的,并且此函数返回一个固定的List,该列表在每次交互时都会更改,则后续执行中的更改可能会影响之前未完成的执行。
这是由于以下事实: cellsWithAgents = getNonEmptyCells();
不会创建副本,而是创建对getNonEmptyCells()
返回值的getNonEmptyCells()
。 因此,如果此方法重用了返回对象,则第一次执行可能会相信有两个,但是伴随的线程将内容大小更改为小于2。
问题是,程序在cellsWithType.get(i)
上cellsWithType.get(i)
异常。 您可以做的是在if (null == cellsWithType.get(i))
处设置一个断点,然后尝试对其进行调试。 或更改为
if (i >= cellsWithType.size())
pass = 1; // breakpoint here
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.