Java-索引越界异常:索引:1,大小:2
在处理某个java项目时,我遇到了一个特殊的错误:Java-索引越界异常:索引:1,大小:2,java,nullpointerexception,indexoutofboundsexception,Java,Nullpointerexception,Indexoutofboundsexception,在处理某个java项目时,我遇到了一个特殊的错误: java.lang.IndexOutOfBoundsException: Index: 1, Size: 2 怎么会有索引越界异常?索引1意味着它试图获取第二个元素,大小2意味着有两个元素,所以应该没有问题,不是吗 背景: 我有以下功能: public int howManyAgents(){ // cell is a class that can have 0 or multiple objects // I get a l
java.lang.IndexOutOfBoundsException: Index: 1, Size: 2
怎么会有索引越界异常?索引1意味着它试图获取第二个元素,大小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;
}
我想调试代码,但是这个函数在程序运行时会被多次调用,空指针异常会在不同的时间点出现(10秒后1分钟后5分钟后)。因此,我尝试提出一种方法,在单元格为空时设置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的null指针异常,并在那里设置了一个断点。似乎cellsWithAgents有时包含null。这很可能是因为@rlinden所说的并发性
关于并发:有些单元格可以包含代理。可以在细胞之间移动的代理数量可变。有一个特殊的代理尝试计算有多少移动代理(使用此函数)。
因此,只有一个代理(线程)可以使用此函数,但多个代理可以修改单元格(从而干扰getNonEmptyCells()和howManyAgents()结果)
不过,如何才能使索引超出大小为2和索引1的范围?因为并发性,这是不可能的,是吗?因为只有这个线程可以更改列表单元格代理。因此,即使列表中的一个元素变为null,列表仍包含该数量的指针,因此列表的大小不能更改。或者我会以某种方式怀念它吗?
如何解释堆栈跟踪打印索引:1大小:2?新想法 尝试更改循环并查看错误是否仍然存在:
int agentsCount = 0;
for(Cell cell : getNonEmptyCells()) {
if(cell != null) {
agentsCount += cell.howManyAgents();
} else {
System.out.println("Found a null cell");
}
}
我想查看方法
getNonEmptyCells()
的代码。如果您的程序实际上是多线程的,并且此函数返回在每次交互时更改的固定列表,则后续执行中的更改可能会影响以前未完成的执行
这是因为行
cellsWithAgents=getNonEmptyCells()
不创建副本,而是对getNonEmptyCells()
的返回值的引用。因此,如果此方法重用返回对象,则第一次执行可能会认为有两个返回对象,但伴随线程将内容大小更改为小于2。问题是,程序在cellsWithType.get(i)
处引发异常。您可以做的是在if(null==cellsWithType.get(i))
处放置一个断点,然后尝试调试它。或者改成,
if (i >= cellsWithType.size())
pass = 1; // breakpoint here
在放置断点的行上放置断点是无用的。当您尝试访问不存在的
i
th索引时,会发生此错误。至于为什么超出范围,我会继续寻找。为什么cellsWithType之间的比较为空?至于这个异常是如何发生的,我无法理解,但我注意到的是:您迭代CellsWithAgent,但使用该索引访问cellsWithType。是的,复制代码时这是一个错误。我已经修复了它,它与列表单元格swithagents相同。@Arc676起初我有一个空指针异常,这就是为什么我尝试了它,但后来我得到了一个索引越界异常。好像有点变了。我现在真的不知道,事情就是这样。哦,该死,我很抱歉。那是个错误,我刚把它修好。这是同一个列表单元格,因为您的代码(现在已修复)或问题(您仍然有错误?)中存在打字错误。啊,您确定是该列表引发了错误吗?在那条线上?可能不是howManyAgents()?这是在问题中,我仍然有错误。堆栈轨迹正好显示了这条线,所以我想这是因为这里。无论如何,howManyAgents()返回映射的大小,但它不适用于索引。请参阅我的编辑以更改循环,希望至少解决您的问题(但不解释)。是的,复制代码时出现了错误。我已经修好了,它是相同的列表。我为这个错误感到抱歉。是的,似乎是因为并发性。非常感谢。我刚刚在代码块周围放了一个synchronized,没有更多的错误。Java怎么会因为并发修改而抛出这样一个奇怪的错误,这很奇怪。这种奇怪是可以解释的。为了提高性能,size()方法只在循环开始时调用。之后,循环假定它保持不变(在2处)。当您在一个同步进程中更改列表时,循环不会得到通知,因此会尝试查找列表中不再存在的元素。哦,好的。这是有道理的。谢谢!
int agentsCount = 0;
for(Cell cell : getNonEmptyCells()) {
if(cell != null) {
agentsCount += cell.howManyAgents();
} else {
System.out.println("Found a null cell");
}
}
if (i >= cellsWithType.size())
pass = 1; // breakpoint here