繁体   English   中英

Java-索引越界异常:索引:1,大小:2

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM