You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java固定长度循环触发ArrayIndexOutOfBoundsException问题求助

解决数组越界异常的问题

首先,咱们直接定位问题根源:你遇到的ArrayIndexOutOfBoundsException: length=128; index=128,是因为代码中计算的x值超出了bytes数组的有效索引范围——bytes数组长度是128,所以合法索引是0到127,但你的计算逻辑会让x等于128,直接触发越界。

问题分析

看你循环里的这行代码:

int x = (int) Math.ceil(i * 8.5);

当i=15时,15*8.5=127.5,Math.ceil()会把它向上取整为128,这时候访问bytes[128]就触发了异常。而且随着i增大,x会远大于127,问题会持续出现。你之前修改循环次数(改成128或者i<=120)完全没触碰到这个核心问题,所以当然没用。

另外,你的points数组初始化逻辑也有隐患:

if (points == null || points.length < bytes.length * 4) {
    points = new float[bytes.length * 4];
}

你循环要生成120组数据(每组4个float),也就是需要120*4=480个元素。如果bytes.length*4小于480(比如bytes长度小于120),后续给points[i*4+3]赋值时也会触发越界。

解决方案

1. 修正x的计算逻辑,确保不超出bytes的索引范围

我们需要把120个循环的i值,均匀映射到bytes数组的0到127索引上,而不是用固定的8.5乘数。可以用线性映射的方式:

int x = (int) Math.round(i * (bytes.length - 1) / 119.0);

或者用Math.min兜底,防止意外越界:

int x = Math.min((int) Math.ceil(i * (bytes.length - 1) / 119.0), bytes.length - 1);

这样i从0到119时,x会从0平滑过渡到127,完全不会超出bytes的合法索引范围。

2. 修正points数组的初始化逻辑

既然你固定要生成120组数据,就应该直接根据循环次数来初始化points,而不是依赖bytes的长度:

if (points == null || points.length < 120 * 4) {
    points = new float[120 * 4];
}

这样不管bytes长度是多少,points都能容纳所有循环生成的元素。

修改后的完整onDraw关键代码片段

@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) {
        // 修正points数组初始化逻辑
        if (points == null || points.length < 120 * 4) {
            points = new float[120 * 4];
        }
        double angle = 0;
        for (int i = 0; i < 120; i++, angle += 3) {
            // 修正x的计算逻辑,映射到bytes的合法索引
            int x = (int) Math.round(i * (bytes.length - 1) / 119.0);
            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)));
        }
        canvas.drawLines(points, paint);
    }
    super.onDraw(canvas);
}

额外建议

你添加的try-catch虽然能避免崩溃,但会让部分数据无法生成,导致可视化效果异常。修复上述两个问题后,完全可以移除这个try-catch块,让代码更干净。

内容的提问来源于stack exchange,提问作者Ankit Suda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:13:46