java和.length上的数组边界

Fra*_*zoa 5 java android

keys数组定义如下:

    keys = new char[] {resolv, '?', '?', '?', '?', '?', '?', 
                                '?', '?', '?', '?', '?', '?', 
                                '?', '?', '?', '?', '?', '?', 
                                '?', '?', '?', '?', '?', '?', 
                                '?', '?', '?', '?', '?', '?',
                                '?', '?', '?'};
Run Code Online (Sandbox Code Playgroud)

'resolv'是一个常量char值0x00,但这与此问题无关.

现在,这段代码有时会引发"java.lang.ArrayIndexOutOfBoundsException:length = 34; index = 34"异常:

protected void LoadKeyRects() {
    keyRects = new Rect[keys.length];
    // Solve key
    keyRects[0] = resRect;


    // Rest of keys
    int x, y;
    for (int i=1; i<keys.length; i++) {
        y = 214 + ( 87 * ((i-1)/11));
        x = 7 + (((i-1)%11)*71);
        keyRects[i] = new Rect (x, y, x+71, y+87);
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我还没有能够自己重现错误,但我从第三方设备的BugSense获得了足够的报告来关注它.似乎有时keyRects [i]可能会引用keyRects [keys.length]尽管i

有任何想法吗?

Tad*_*riz 4

我可以在循环中看到问题for。如果您不访问该字段本身,您可以使用超出范围的字段来结束迭代,这完全是错误的。另外,如果你这样做了,你应该采取不同的做法。两个例子:

protected void LoadKeyRects() {
    keyRects = new Rect[keys.length];
    // Solve key
    keyRects[0] = resRect;


    // Rest of keys
    int x, y;
    for (int i=1; i<keyRects.length; i++) {
        y = 214 + ( 87 * ((i-1)/11));
        x = 7 + (((i-1)%11)*71);
        keyRects[i] = new Rect (x, y, x+71, y+87);
    }
}
Run Code Online (Sandbox Code Playgroud)

这将正常工作,没有任何ArrayIndexOutOfBoundsException确定。如果您需要访问甚至修改keys数组,请这样做:

protected void LoadKeyRects() {
    final char[] localKeys = keys;

    keyRects = new Rect[localKeys.length];
    // Solve key
    keyRects[0] = resRect;


    // Rest of keys
    int x, y;
    for (int i=1; i<localKeys.length; i++) {
        y = 214 + ( 87 * ((i-1)/11));
        x = 7 + (((i-1)%11)*71);
        keyRects[i] = new Rect (x, y, x+71, y+87);
    }

    // if you need to change the keys, uncomment the next line
    // keys = localKeys;
}
Run Code Online (Sandbox Code Playgroud)