Java不使用ArrayList读取学生文本数据到数组空指针报错如何修复
问题修复方案
你遇到的报错和Student类本身无关,是主逻辑存在多处编码错误,具体问题和修复方案如下:
- 空指针直接原因:创建
Student数组后,数组的每个位置默认是null,你没有实例化Student对象就直接给对象属性赋值,触发空指针异常。你虽然写了构造方法,但全程没有调用构造方法创建对象。 - 数组长度计算错误:你统计文件元素时调用
next()逐个单词计数,得到的是文件总单词数,而每条学生记录对应4个单词(姓名+三科成绩),数组长度应该是总单词数/4,而不是总单词数。 - main方法逻辑错误:调用
readData()拿到结果数组后,你又重新创建了一个全空的Student数组覆盖原有结果,就算读取逻辑正确最后也只会打印null。 - 文件读取额外问题:你的txt文件最后一行是表头,直接读取会尝试把字符串
Name转为int触发类型转换错误,建议删除表头或读取时跳过首行。
修复后的代码
Student类(修正原构造方法笔误)
public class Student { public String name; public int physic; public int chemistry; public int math; public double average; // 平均分可在构造时直接计算,无需作为参数传入 public Student(String name, int physic, int chemistry, int math) { this.name = name; this.physic = physic; this.chemistry = chemistry; this.math = math; this.average = (physic + chemistry + math) / 3.0; // 需要保留两位小数可放开下面注释 // this.average = Math.round(this.average * 100) / 100.0; } // 重写toString方法方便打印输出 @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", physic=" + physic + ", chemistry=" + chemistry + ", math=" + math + ", average=" + average + '}'; } }
Main2类
import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; import java.util.Arrays; public class Main2 { public static void main(String[] args) throws FileNotFoundException { String filename = "students.txt"; Student[] record = readData(filename); // 按平均分降序排序,不需要排序可删除这段 Arrays.sort(record, (o1, o2) -> Double.compare(o2.average, o1.average)); for (int i = 0; i < record.length; i++) { System.out.println(record[i]); } } private static Student[] readData(String filename) throws FileNotFoundException { int wordCount = 0; Scanner s1 = new Scanner(new File(filename)); // 跳过txt表头行,如果已删除txt里的表头可注释掉这行 s1.nextLine(); // 统计总单词数 while (s1.hasNext()) { wordCount++; s1.next(); } // 每条学生记录占4个单词,计算学生人数作为数组长度 int studentCount = wordCount / 4; Student[] studentRecord = new Student[studentCount]; Scanner s2 = new Scanner(new File(filename)); // 同样跳过表头,删了表头就注释这行 s2.nextLine(); for (int i = 0; i < studentCount; i++) { // 先读取属性,再实例化Student对象存入数组 String name = s2.next(); int physic = s2.nextInt(); int chemistry = s2.nextInt(); int math = s2.nextInt(); studentRecord[i] = new Student(name, physic, chemistry, math); } s1.close(); s2.close(); return studentRecord; } }
内容的提问来源于stack exchange,提问作者shaman
相关产品推荐
相关产品推荐

