Java:返回含多类型属性的对象至ArrayList时程序终止问题
问题描述
我尝试把包含String和int类型属性的Student对象存入ArrayList,但程序直接终止,没有返回对象。enterTeacher()方法能正常返回仅含String属性的Teacher对象,但enterStudents()方法在输入成绩后就停止运行。我怀疑是因为Student同时有String和int属性导致的,试过创建Student对象数组,但也没法返回这个数组。
原代码
import java.util.ArrayList; import java.util.Scanner; public class PrintReport { Scanner in = new Scanner(System.in); char answer; ArrayList<Displayable> list = new ArrayList<Displayable>(); public PrintReport() { System.out.println("First You Need To Create A Classroom"); do { Displayable c = enterClassroom(); list.add(c); System.out.print("Enter another class room (Y or N)? "); answer = in.next().toUpperCase().charAt(0); in.nextLine(); } while (answer != 'N'); report(list); } public Displayable enterClassroom() { ArrayList<Displayable> studentList = new ArrayList<Displayable>(); System.out.print("Enter Room Number: "); int room = in.nextInt(); in.nextLine(); System.out.println("Now you need to enter a teacher for the classroom."); Displayable teacher = enterTeacher(); System.out.println("Now you need to Add Students for the classroom."); Displayable Student = enterStudents(); do { } while (answer != 'N'); return new Classroom(room, teacher, studentList); } public Displayable enterTeacher() { System.out.print("Enter first name of teacher: "); String fName = in.nextLine(); System.out.print("Enter last name of teacher: "); String lName = in.nextLine(); System.out.print("Enter subject of teacher: "); String subject = in.nextLine(); Displayable teacher = new Teacher(fName, lName, subject); return teacher; } public Displayable enterStudents() { int studentID; System.out.print("Enter student id(greater than 0): "); studentID = Integer.parseInt(in.nextLine()); System.out.print("Enter first name of student: "); String fName = in.nextLine(); System.out.print("Enter last name of student: "); String lName = in.nextLine(); int grade = 0; System.out.print("Enter final grade of student(0-100): "); grade = Integer.parseInt(in.nextLine()); Displayable Student = new Student(fName, lName, studentID, grade); return Student; } void report(ArrayList<Displayable> list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).display()); } } public static void main(String[] args) { PrintReport pr = new PrintReport(); } }
问题分析与修复
核心问题1:Scanner输入换行符残留导致异常
enterClassroom()中用in.nextInt()读取教室号后,虽然调用了一次in.nextLine(),但后续enterStudents()里用Integer.parseInt(in.nextLine())时,可能读取到空字符串(因为之前的输入操作遗留了换行符),触发NumberFormatException直接终止程序。
核心问题2:死循环卡死程序
enterClassroom()里有个空的do-while循环:
do { } while (answer != 'N');
这个循环没有任何输入或修改answer的逻辑,会无限卡死程序。
核心问题3:Student对象未加入列表
你调用enterStudents()创建了Student对象,但没把它添加到studentList中,最终返回的Classroom对象里的学生列表是空的。
修复后的完整代码
import java.util.ArrayList; import java.util.Scanner; public class PrintReport { Scanner in = new Scanner(System.in); char answer; ArrayList<Displayable> list = new ArrayList<>(); public PrintReport() { System.out.println("首先你需要创建一个班级"); do { Displayable c = enterClassroom(); list.add(c); System.out.print("是否创建另一个班级(Y/N)? "); answer = in.next().toUpperCase().charAt(0); in.nextLine(); // 清除换行符 } while (answer != 'N'); report(list); } public Displayable enterClassroom() { ArrayList<Displayable> studentList = new ArrayList<>(); System.out.print("输入教室编号: "); int room = in.nextInt(); in.nextLine(); // 清除nextInt()后的换行符 System.out.println("现在请输入该班级的老师信息。"); Displayable teacher = enterTeacher(); System.out.println("现在请添加该班级的学生。"); // 替换死循环为添加多个学生的逻辑 do { Displayable student = enterStudents(); studentList.add(student); // 将学生加入列表 System.out.print("是否添加另一个学生(Y/N)? "); answer = in.next().toUpperCase().charAt(0); in.nextLine(); // 清除换行符 } while (answer != 'N'); return new Classroom(room, teacher, studentList); } public Displayable enterTeacher() { System.out.print("输入老师名字: "); String fName = in.nextLine(); System.out.print("输入老师姓氏: "); String lName = in.nextLine(); System.out.print("输入老师教授科目: "); String subject = in.nextLine(); return new Teacher(fName, lName, subject); } public Displayable enterStudents() { int studentID; System.out.print("输入学生ID(大于0): "); // 用nextInt()避免换行符问题,之后清除换行 studentID = in.nextInt(); in.nextLine(); System.out.print("输入学生名字: "); String fName = in.nextLine(); System.out.print("输入学生姓氏: "); String lName = in.nextLine(); int grade = 0; System.out.print("输入学生期末成绩(0-100): "); grade = in.nextInt(); in.nextLine(); // 清除换行符 return new Student(fName, lName, studentID, grade); } void report(ArrayList<Displayable> list) { // 用增强for循环简化遍历 for (Displayable item : list) { System.out.println(item.display()); } } public static void main(String[] args) { new PrintReport(); } } // 补充必要的接口和实体类定义 interface Displayable { String display(); } class Teacher implements Displayable { private String fName, lName, subject; public Teacher(String fName, String lName, String subject) { this.fName = fName; this.lName = lName; this.subject = subject; } @Override public String display() { return "老师: " + fName + " " + lName + ", 科目: " + subject; } } class Student implements Displayable { private String fName, lName; private int studentID, grade; public Student(String fName, String lName, int studentID, int grade) { this.fName = fName; this.lName = lName; this.studentID = studentID; this.grade = grade; } @Override public String display() { return "学生: " + fName + " " + lName + ", ID: " + studentID + ", 成绩: " + grade; } } class Classroom implements Displayable { private int roomNumber; private Displayable teacher; private ArrayList<Displayable> students; public Classroom(int roomNumber, Displayable teacher, ArrayList<Displayable> students) { this.roomNumber = roomNumber; this.teacher = teacher; this.students = students; } @Override public String display() { StringBuilder sb = new StringBuilder(); sb.append("教室编号: ").append(roomNumber).append("\n"); sb.append(teacher.display()).append("\n"); sb.append("学生列表:\n"); for (Displayable s : students) { sb.append("- ").append(s.display()).append("\n"); } return sb.toString(); } }
关键修复点
- 处理Scanner换行符问题:用
nextInt()读取数字后立即调用in.nextLine()清除遗留的换行符,避免后续nextLine()读取空字符串导致异常。 - 替换死循环:把
enterClassroom()中的空循环改成可多次添加学生的逻辑,每次添加后询问是否继续。 - 添加学生到列表:将创建的Student对象加入
studentList,确保Classroom对象包含有效学生数据。 - 简化代码:用增强for循环替换普通for循环,遍历更简洁。
内容的提问来源于stack exchange,提问作者Che Man
相关产品推荐
相关产品推荐

