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

Java数组越界异常排查:跨类数组初始化与输入问题

问题分析与解决

核心错误原因

  1. 数组初始化时机错误:
    你在value类中声明数组时直接用size初始化,但此时size作为类成员变量,默认值是0,所以name和marks数组的长度都是0。后续在主方法中给mar.size赋值,并不会改变已经创建好的数组长度,循环访问mar.name[i]时自然触发ArrayIndexOutOfBoundsException。

  2. Scanner输入残留换行符:
    使用sc.nextInt()读取size后,输入缓冲区会留下一个换行符,后续的sc.nextLine()会直接读取这个空行,导致第一个姓名输入为空,甚至打乱循环逻辑。

修复方案

步骤1:调整数组初始化时机

修改value类,不在成员变量声明时初始化数组,而是在size确定后动态创建。这里给value类添加带参数的构造方法,传入size时完成数组初始化:

class value{
    int size;
    String name[];
    float marks[];
    float sum=0;

    // 带参数构造方法,初始化size和数组
    value(int size){
        this.size = size;
        this.name = new String[size];
        this.marks = new float[size];
    }

    double total(){     
        for(float i: marks) 
            sum+=i;
        return sum;
    }

    double average(){
        return sum/(marks.length);
    }

    char grade(){
        if(average()>=90)
            return 'A';
        else if(average()>=80 && average()<90)
            return 'B';
        else
            return 'C';    
    }
}

步骤2:处理Scanner换行符问题

在主方法中,读取size后调用sc.nextLine()清空输入缓冲区的换行符,避免干扰后续姓名输入:

public class StudentMarks {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        
        System.out.printf("Enter size : ");
        int size = sc.nextInt();
        sc.nextLine(); // 吃掉nextInt留下的换行符
        
        // 用输入的size创建value对象
        value mar=new value(size);
        
        System.out.println(mar.size);

        System.out.printf("\nEnter names : ");
        for(int i=0; i<mar.size; i++){
            mar.name[i]= sc.nextLine();
        }

        System.out.printf("\nEnter marks : ");
        for(int i=0; i<mar.size; i++){
            mar.marks[i]= sc.nextFloat();
        }

        // 输出结果
        for(String i: mar.name){
            System.out.println(i);
        }
        System.out.println(mar.average());
        System.out.println(mar.grade());
        
        sc.close(); // 关闭Scanner,避免资源泄漏
    }
}

额外优化建议

  • 类名遵循Java命名规范,把value改为StudentRecord或MarksData这类有意义的名称。
  • 成员变量建议设置为private,提供getter/setter方法,符合面向对象的封装原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:52:58