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

Java运行时异常:ArrayIndexOutOfBoundsException(索引130越界)求助

解决Java数组越界异常(ArrayIndexOutOfBoundsException)的问题

错误原因分析

你遇到的Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 130 out of bounds for length 130异常,直接触发点在init方法的第55行:variableinput[i] = (char) c;。当i的值走到130时,超出了variableinput数组的合法索引范围(数组长度130,索引只能是0-129),具体原因有这几个:

  • 超长行未处理:输入文件里存在某一行的字符数超过129个,当读取到第130个字符时,i自增到130,赋值时直接越界。
  • 换行符处理不完整:Windows系统的换行是CR(13)+LF(10)组合,你的代码只把LF(10)当作换行标志。当读取到CR(13)时,会先把它存入数组让i自增,如果此时数组已经被填满(i=129),加上这个CR就会让i=130,下一次赋值就触发异常。
  • 无边界限制逻辑:代码里没有限制i的最大值,哪怕数组已经满了,还是会继续往里面写数据,必然触发越界。

最优解决方案:改用按行读取(规避手动字符处理的坑)

手动逐个字符读取并维护数组的方式很容易出错,推荐用BufferedReader的readLine()方法按行读取文件——这样能直接拿到每一行的完整字符串,完全不用操心数组长度不够的问题。修改后的代码如下:

import java.io.*; 
public class Datachange { 
    public class variables { 
        private char [] body; 
        private int ID; 
        private int population; 
        private int populationchilds; 
        private int populationchildspoverty; 
        private double populationchildpovertypercent; 
        
        variables(char [] input) { 
            body = input; 
            // 先做长度检查,避免后续截取数组时越界
            if (body.length < 108) {
                throw new IllegalArgumentException("输入行长度不足,无法解析数据");
            }
            char[] stateID = java.util.Arrays.copyOfRange(body,0,2); 
            ID = Integer.parseInt(new String(stateID).trim()); 
            char[] totalpopulation = java.util.Arrays.copyOfRange(body,83,90); 
            population = Integer.parseInt(new String(totalpopulation).trim()); 
            char [] childpopulation = java.util.Arrays.copyOfRange(body,92,99); 
            populationchilds = Integer.parseInt(new String(childpopulation).trim()); 
            char [] povertychilds = java.util.Arrays.copyOfRange(body,101,108); 
            populationchildspoverty = Integer.parseInt(new String(povertychilds).trim()); 
        } 
    } 
    public static void main(String[] args) { 
        Datachange DS = new Datachange(); 
        DS.init(); 
    } 
    public void init() { 
        variables dataframe[] = new variables[13486]; 
        try (BufferedReader inputDataframe = new BufferedReader(new FileReader("SmallAreaIncomePovertyEstData.txt"))) { 
            String line; 
            int j = 0; 
            while((line = inputDataframe.readLine())!=null) { 
                // 直接把行字符串转成char数组,自动适配每行长度
                char variableinput[] = line.toCharArray(); 
                dataframe[j] = new variables(variableinput); 
                j++; 
                // 防止读取行数超过数组容量
                if (j >= dataframe.length) {
                    System.out.println("数据行数超过数组上限,已停止读取");
                    break;
                }
            } 
        } catch(IOException except) { 
            System.out.println("There is Input/Output Error:" + except.getMessage()); 
        } 
        this.newdata(dataframe); 
    } 
    public variables[] newdata(variables[] dataset) { 
        variables[] newdata=new variables[57]; 
        try (BufferedWriter outData = new BufferedWriter(new FileWriter("SmallAreaIncomePovertyEstDatanew.txt"))) { 
            int stateID = 1; //First ID 
            int statePop= 0; 
            int stateChdPop=0; 
            int stateChdPovertyPop=0; 
            // 只处理已初始化的数组元素
            for(int i=0;i<dataset.length && dataset[i]!=null;i++) { 
                if (dataset[i].ID == stateID) { 
                    statePop += dataset[i].population; 
                    stateChdPop += dataset[i].populationchilds; 
                    stateChdPovertyPop += dataset[i].populationchildspoverty; 
                } else { 
                    double stateChdPovertyPopPercent=0; 
                    if (stateChdPop != 0) { 
                        stateChdPovertyPopPercent = (double) stateChdPovertyPop/stateChdPop * 100; 
                    } else { 
                        stateChdPovertyPopPercent = 0; 
                    } 
                    outData.append(stateID + "\t" + statePop + "\t" + stateChdPop + "\t" + stateChdPovertyPop+ "\t" + stateChdPovertyPopPercent + "\n"); 
                    statePop = 0; 
                    stateChdPop = 0; 
                    stateChdPovertyPop = 0; 
                    i--; 
                    stateID++; 
                } 
            } 
            // 补充写入最后一个州的统计数据
            double stateChdPovertyPopPercent=0; 
            if (stateChdPop != 0) { 
                stateChdPovertyPopPercent = (double) stateChdPovertyPop/stateChdPop * 100; 
            } else { 
                stateChdPovertyPopPercent = 0; 
            } 
            outData.append(stateID + "\t" + statePop + "\t" + stateChdPop + "\t" + stateChdPovertyPop+ "\t" + stateChdPovertyPopPercent + "\n"); 
        } catch(IOException except) { 
            System.out.println("I/O Error:" + except.getMessage()); 
        } 
        return newdata; 
    } 
}

额外优化说明

  1. 在variables构造函数里加了行长度检查,避免因行太短导致copyOfRange操作触发新的越界异常。
  2. init方法里增加了数组容量校验,防止读取的行数超过dataframe的初始化长度。
  3. newdata方法的循环里增加了dataset[i]!=null判断,避免处理未初始化的空数组元素。
  4. 补充了最后一个州的数据写入逻辑——原代码会漏掉最后一组州的统计结果。

内容的提问来源于stack exchange,提问作者Kj Analytica

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:22:37