使用变量声明的数组大小时的ArrayIndexOutOfBoundsException

时间:2013-09-09 09:23:48

标签: java arrays exception indexoutofboundsexception

当我用变量声明数组大小时,我得到ArrayIndexOutOfBoundsException,但是当我用数字声明它时,我没有。

    static Student[] readFile(String filename) {
    .........

    LineNumberReader lnr = null;
    try {
        lnr = new LineNumberReader(new FileReader(new File(filename)));
        lnr.skip(Long.MAX_VALUE);
        len = lnr.getLineNumber();
        lnr.close();
    } catch (IOException e1) {
        e1.printStackTrace();
    }

    len--; // discount the first line
    len = (len > 40) ? 40 : len;
    Student[] s = new Student[len]; <------- replacing len with a number resolves it

    try {
        f = new BufferedReader(new FileReader(new File(filename)));
        while ((line = f.readLine()) != null) {
            ......... 

            s[roll] = new Student(SID, marks); <--- Exception thrown here
            roll++;

            if (roll == 41) {
                f.close();
                throw new CustomException("41st Student!!");
            }
        }
        f.close();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (CustomException e) {
        System.out.println("Too many students in the class!");
    }

    return s;
}

有人可以解释一下为什么当编译器本身不知道绑定时,编译器会认为我会超出界限吗?

谢谢!

5 个答案:

答案 0 :(得分:4)

ArrayIndexOutOfBoundsException RuntimeException 。如果它发生了,那么你肯定会超出范围。
roll < len之前检查s[roll] = new Student(SID, marks);

另请注意,Java(以及大多数语言)中的数组是 zeor-based 。因此,如果您有一个大小为N的数组,则索引从0N - 1N的总和)。

答案 1 :(得分:0)

s[roll] = new Student(SID, marks); <--- Exception thrown here
roll++;

if (roll == 41) {
    f.close();
    throw new CustomException("41st Student!!");
}

您声明大小为40的数组。这意味着您可以访问0-39。然后,您尝试将新的Student对象添加到4041。您的if语句期望值为41即可证明这一点。

答案 2 :(得分:0)

len = (len > 40) ? 40 : len;

在这里,您将数组长度的上限设置为40.如果您的文件包含超过40行,它将在此处给出arrayOutofBound异常:

 s[roll] = new Student(SID, marks); <--- Exception thrown here

所以你确定你的文件永远不会超过40行。如果不是这样,那就像先前指出的那样反过来比较。

     len = (len > 40) ? len : 40;

答案 3 :(得分:0)

  1. 您在哪里定义变量“len”?哪种类型?应该是“int”
  2. 变量“roll”从哪里来?哪种类型有滚?也应该是“int”,
  3. 确保对数组索引使用int值。许多简单类型可以自动转换为int,但结果可能是意外的。

    确保“roll”永远不会高于数组大小!

    记住数组索引从零开始!但大小由一个。 最终结果如下:

    String[] myArr = new String[5];
    myArray.length == 5
    myArray[0] == First entry
    myArray[4] == Last entry!!!
    

    简单循环:

    for (int i = 0; i < myArray.length; i++)
    

    希望有所帮助,但通常你的步调试器应该为你回答这样的问题。

答案 4 :(得分:0)

len = (len > 40) ? 40 : len;

len的值有2种情况,这两种情况都可能导致超出界限:

a。执行上述语句后,假设len初始化为值40.然后,名为s的数组的长度为40。

s[roll] = new Student(SID, marks);

假设roll的值为40.然后,您为索引40分配一个值,即s [40] = value,索引的有效范围是0到39.因此,抛出ArrayIndexOutOfBoundsException

b。假设len小于40。

s[roll] = new Student(SID, marks); 

这里,只要为索引分配的值大于len的大小,就会遇到ArrayIndexOutOfBoundsException

建议:在语句中分配值之前,添加一个数组大小在允许范围内的测试,如下所示:

if(roll < len)
{
    s[roll] = new Student(SID, marks); 
}