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

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();
    }
}

关键修复点

  1. 处理Scanner换行符问题:用nextInt()读取数字后立即调用in.nextLine()清除遗留的换行符,避免后续nextLine()读取空字符串导致异常。
  2. 替换死循环:把enterClassroom()中的空循环改成可多次添加学生的逻辑,每次添加后询问是否继续。
  3. 添加学生到列表:将创建的Student对象加入studentList,确保Classroom对象包含有效学生数据。
  4. 简化代码:用增强for循环替换普通for循环,遍历更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:55:21