【问题标题】:JAVA - Fixed length for loop giving ArrayIndexOutOfBoundsException [duplicate]JAVA-给出ArrayIndexOutOfBoundsException的循环的固定长度[重复]
【发布时间】:2018-06-14 05:03:36
【问题描述】:

嘿,我不知道为什么,但是这个循环不起作用,每次都给我同样的错误。如果您知道修复方法,请回答。而且我无法解决这个问题。

这是我的循环

double angle = 0;

for (int i = 0; i < 120; i++, angle += 3) {
    int x = (int) Math.ceil(i * 8.5);
    int t = ((byte) (-Math.abs(bytes[x]) + 128))
            * (canvas.getHeight() / 4) / 128;

    points[i * 4] = (float) (getWidth() / 2
            + radius
            * Math.cos(Math.toRadians(angle)));

    points[i * 4 + 1] = (float) (getHeight() / 2
             + radius
             * Math.sin(Math.toRadians(angle)));

    points[i * 4 + 2] = (float) (getWidth() / 2
            + (radius + t)
            * Math.cos(Math.toRadians(angle)));

    points[i * 4 + 3] = (float) (getHeight() / 2
            + (radius + t)
            * Math.sin(Math.toRadians(angle)));
}

这是我的错误

E/AndroidRuntime: FATAL EXCEPTION: main

Process: app.androidgrid.faysr, PID: 19297

java.lang.ArrayIndexOutOfBoundsException: length=128; index=128
     at app.androidgrid.faysr.visualizer.view.CircleBarVisualizer.onDraw(CircleBarVisualizer.java:94)
     at android.view.View.draw(View.java:17096)
     at android.view.View.updateDisplayListIfDirty(View.java:16078)

我也尝试将 120 更改为 128 并将 i 更改为 i 但事实并非如此

这是我的 java 类

public class CircleBarVisualizer extends BaseVisualizer {
private float[] points;
private Paint circlePaint;
private int radius;

public CircleBarVisualizer(Context context) {
    super(context);
}

public CircleBarVisualizer(Context context,
                           @Nullable AttributeSet attrs) {
    super(context, attrs);
}

public CircleBarVisualizer(Context context,
                           @Nullable AttributeSet attrs,
                           int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void init() {
    paint.setStyle(Paint.Style.STROKE);
    circlePaint = new Paint();
    radius = -1;
}

@Override
protected void onDraw(Canvas canvas) {
    if (radius == -1) {
        radius = getHeight() < getWidth() ? getHeight() : getWidth();
        radius = (int) (radius * 0.65 / 2);
        double circumference = 2 * Math.PI * radius;
        paint.setStrokeWidth((float) (circumference / 120));
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(4);
    }
    circlePaint.setColor(color);
    canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, circlePaint);
    if (bytes != null) {
        if (points == null || points.length < bytes.length * 4) {
            points = new float[bytes.length * 4];
        }
        double angle = 0;

        try {
            for (int i = 0; i < 120; i++, angle += 3) {
                int x = (int) Math.ceil(i * 8.5);
                int t = ((byte) (-Math.abs(bytes[x]) + 128))
                        * (canvas.getHeight() / 4) / 128;

                points[i * 4] = (float) (getWidth() / 2
                        + radius
                        * Math.cos(Math.toRadians(angle)));

                points[i * 4 + 1] = (float) (getHeight() / 2
                        + radius
                        * Math.sin(Math.toRadians(angle)));

                points[i * 4 + 2] = (float) (getWidth() / 2
                        + (radius + t)
                        * Math.cos(Math.toRadians(angle)));

                points[i * 4 + 3] = (float) (getHeight() / 2
                        + (radius + t)
                        * Math.sin(Math.toRadians(angle)));
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }

        canvas.drawLines(points, paint);
    }
    super.onDraw(canvas);
}}

我也是try-catch所以,它不会让应用崩溃,但结果不是我例外。

【问题讨论】:

  • for 循环将 i 从 0 迭代到 119,但随后代码使用 i 的倍数 (i * 4...) 来寻址只有 128 个元素长的 points 数组中的元素(例外说)。
  • 您正在访问两个数组:points[]bytes[]。后者由x 索引,即ceil(i * 8.5)。对于i == 15x 的值将是 128 (ceil(127.5)),并且也适合您的错误消息。因此,这也可能是一个问题。
  • 您的一个数组的长度为 128,因此您的最大索引为 127,因为您的索引为零。您的循环似乎导致您尝试访问大于数组大小的元素。尝试注释掉每个数组元素调用,看看哪个触发了错误。当i=15 时,您的Math.ceil(i * 8.5) 呼叫将达到128
  • @AnkitSuda 确保您投票并接受答案。

标签: java android arrays for-loop indexoutofboundsexception


【解决方案1】:

对于i = 0 ... 120,在循环的最后一次迭代中使用以下语句:

points[i * 4 + 3]

将尝试访问仅包含 128 个元素的数组 ((119 * 4) + 3 = 479) 的第 479 个元素。

为了填充您的数组,您需要i &lt; 31,因为(31 * 4) + 3 = 127

【讨论】:

    【解决方案2】:

    java.lang.ArrayIndexOutOfBoundsException: length=128; index=128 -> 这意味着您正在尝试访问仅包含 128 个元素的数组的第 129 个元素。

    请记住,在 Java 中数组是基于 0 的,因此在您的情况下有效索引从 0 到 127 不等

    【讨论】:

    • 但循环应该在 120 结束
    • i 以 120 结尾,但您使用 i * 4 等索引。当 i 为 100 时,这意味着您将尝试获取 400 索引。但是您没有显示足够的代码让我们确定是哪一行导致了问题
    • 好的,我正在更新代码。
    • 假设 CircleBarVisualizer 是您创建的一个类,检查第 94 行,这就是它发生的地方。
    • 但是课程在 89 结束:P
    【解决方案3】:

    即使你有 for 循环,它会迭代索引 0120,但在你的 for 循环中,你试图访问不同的索引(i * 4i * 4 + 等),即导致实际问题。

    想象一下,您有 points 大小为 2 的数组。现在,在第一次迭代中,i 将是 0,但您将尝试访问元素 i * 4 + 3,这将等效于 3。但是,points 数组大小为 2。

    因为,您正在尝试访问元素 i * 4 + 3(这将是每次迭代的高端)。我建议将您的for 循环更改为避免ArrayIndexOutOfBoundsException(如果数组大小为120

     for (int i = 0; (i * 4 + 3) < 120; i++, angle += 3) {
    

    【讨论】:

      【解决方案4】:

      您必须查看“points”数组的大小。考虑到您的代码,其大小应至少为 (119 * 4 +3),即 479。

      "points" 数组大小是 4 * "bytes" 数组大小,但您的代码没有显示什么是 "bytes" 数组大小;可能是在祖先类中定义的东西。

      【讨论】:

        猜你喜欢
        • 2019-02-09
        • 2011-07-20
        • 1970-01-01
        • 2020-01-10
        • 1970-01-01
        • 1970-01-01
        • 2022-11-15
        • 1970-01-01
        • 2011-11-19
        相关资源
        最近更新 更多