Java创建Student类读取成绩文件遇问题,求正确实现方案
解决读取文件创建Student对象时的成绩提取问题
我看了你遇到的问题,核心是在读取文件内容时,Scanner方法混用导致的读取错位,再加上几个细节问题,才没法正确创建Student对象。咱们一步步拆解问题并解决:
先说说你现有代码里的几个关键问题
- Scanner读取方法混用导致错位:第一行是考试数量
3,你用input.nextLine()读取时,第一次循环会读这行,但后续用nextInt()读完数字后,并不会消耗换行符,下一次nextLine()会读到空字符串,直接导致姓名读取错误。 - 成绩数组引用重复:你只创建了一个
grade数组,每次循环都往里面覆盖新成绩,最后所有Student对象都会指向同一个数组,所有学生的成绩都会变成最后一组的值。 - 提前关闭Scanner:你在while循环内部调用了
input.close(),第一次循环结束后Scanner就被关闭,后续根本没法继续读取其他学生的数据。 - 数组打印方式错误:直接调用
grade.toString()或打印getStudentGrades(),输出的是数组的哈希值,不是实际成绩内容,得用Arrays.toString()才能看到数组里的具体数值。
修正后的完整代码
主程序读取文件的代码
import java.io.File; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class StudentReader { public static void main(String[] args) { try { File file = new File("info1.txt"); Scanner input = new Scanner(file); // 读取第一行的考试数量,然后消耗掉换行符 int examCount = input.nextInt(); input.nextLine(); // 用动态列表存储学生,避免提前固定数组长度的麻烦 List<Student> studentList = new ArrayList<>(); while (input.hasNextLine()) { // 读取整行学生数据 String studentLine = input.nextLine(); // 按空格分割成姓名+成绩的字符串数组 String[] parts = studentLine.split(" "); String studentName = parts[0]; int[] grades = new int[examCount]; // 把分割后的字符串转成int类型的成绩 for (int i = 0; i < examCount; i++) { grades[i] = Integer.parseInt(parts[i + 1]); } // 创建Student对象并加入列表 Student student = new Student(studentName, grades); studentList.add(student); // 打印测试:用Arrays.toString()输出数组内容 System.out.println(student.getName() + " " + Arrays.toString(student.getStudentGrades())); } input.close(); // 如果需要转成数组的话 Student[] students = studentList.toArray(new Student[0]); } catch (FileNotFoundException e) { System.out.println("找不到目标文件:" + e.getMessage()); } } }
规范后的Student类
public class Student { // 遵循Java命名规范:变量名小驼峰,成员变量封装为private private String name; private int[] studentGrades; public Student(String name, int[] studentGrades) { this.name = name; // 克隆数组,避免外部修改影响对象内部数据 this.studentGrades = studentGrades.clone(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int[] getStudentGrades() { // 返回数组副本,防止外部直接修改内部数组 return studentGrades.clone(); } public void setStudentGrades(int[] studentGrades) { this.studentGrades = studentGrades.clone(); } }
关键改动说明
- 正确处理Scanner换行:用
nextInt()读取考试数量后,调用input.nextLine()消耗掉该行的换行符,确保后续nextLine()能正确读取每个学生的完整行数据。 - 按行分割处理数据:把每个学生的行用
split(" ")拆成字符串数组,直接提取姓名和成绩,完全避免了Scanner方法混用的错位问题。 - 每个学生独立的成绩数组:每次循环都新建一个
grades数组,保证每个Student对象拥有自己独立的成绩数据,不会互相覆盖。 - 数组安全封装:在Student类的构造方法和getter里克隆数组,避免外部代码直接修改对象内部的成绩数组,保证数据安全性。
- 动态存储学生:用
ArrayList代替固定长度的数组,不用提前预估学生数量,更灵活健壮。
内容的提问来源于stack exchange,提问作者Alihan Aydın
相关产品推荐
相关产品推荐

