Java中Scanner读取文本为Vehicle子类Car字段赋值失败求助
问题:子类Car的字段无法从文本文件正确赋值
我是Java新手,开发包含三个类的项目时遇到问题:用Scanner读取文本文件给Vehicle和其子类Car的字段赋值,仅Vehicle的字段成功,Car的isConvertible始终为false、numOfDoors始终为0。
问题根源
- Vehicle类readDetails方法错误处理Scanner:父类方法中调用
scanner.nextLine()并新建、关闭Scanner,直接耗尽传入的Scanner资源,导致子类后续无法读取剩余字段。 - Car类readDetails方法逻辑冗余:子类中重复写了读取整行的逻辑,但传入的Scanner是针对单行文本的,无多行可读取,且父类已关闭Scanner,子类无法继续读取。
- Vehicle类字段冗余:Vehicle中定义了
isConvertible和numOfDoors,这两个是Car专属字段,属于设计冗余。 - Car类构造方法无效赋值:
isConvertible = this.isConvertible;这类代码无意义,默认值本身就是false和0。 - Car类printDetails依赖未实现方法:
ShowVehicleModel()等方法不存在,会导致编译错误。
修改方案
1. 重构Vehicle类
- 删除冗余的
isConvertible和numOfDoors字段 - 修改readDetails方法,直接使用传入的Scanner读取字段,不新建/关闭Scanner
- 添加getter方法供子类访问私有字段
2. 重构Car类
- 删除构造方法中的无效赋值
- 修改readDetails方法,去掉整行读取逻辑,直接调用父类方法后读取专属字段
- 修复printDetails方法,使用父类getter获取字段值
3. 调整RentShop类
- 保持当前单行读取逻辑,确保传入Car的Scanner是针对单行文本的
修改后的代码
Vehicle类
import java.util.NoSuchElementException; import java.util.Scanner; public class Vehicle { private String vehicleModel; String vehicleCode; private int timesRented; private boolean onRent; private int price; private int vehiclePlateNum; public Vehicle() { } public void printDetails() { System.out.println("Vehicle model: " + vehicleModel + "; code: " + vehicleCode + "; timesRented: " + timesRented + "; onRent: " + onRent + "; price: " + price + "; vehiclePlateNum: " + vehiclePlateNum); } public void readDetails(Scanner scanner) { try { vehicleModel = scanner.next().trim(); vehicleCode = scanner.next().trim(); timesRented = Integer.parseInt(scanner.next().trim()); onRent = Boolean.parseBoolean(scanner.next().trim()); price = Integer.parseInt(scanner.next().trim()); vehiclePlateNum = Integer.parseInt(scanner.next().trim()); } catch (NoSuchElementException e) { System.out.println("Error reading vehicle data: " + e.getMessage()); } } // 供子类使用的getter方法 public String getVehicleModel() { return vehicleModel; } public String getVehicleCode() { return vehicleCode; } public int getTimesRented() { return timesRented; } public boolean isOnRent() { return onRent; } public int getPrice() { return price; } public int getVehiclePlateNum() { return vehiclePlateNum; } }
Car类
import java.util.NoSuchElementException; import java.util.Scanner; public class Car extends Vehicle { private boolean isConvertible; private int numOfDoors; public Car() { super(); } @Override public void printDetails() { System.out.println("Vehicle model: " + getVehicleModel() + "; code: " + getVehicleCode() + "; timesRented: " + getTimesRented() + "; onRent: " + isOnRent() + "; price: " + getPrice() + "; vehiclePlateNum: " + getVehiclePlateNum() + "; isConvertible: " + isConvertible + "; numOfDoors: " + numOfDoors); } @Override public void readDetails(Scanner scanner) { try { super.readDetails(scanner); this.isConvertible = Boolean.parseBoolean(scanner.next().trim()); this.numOfDoors = Integer.parseInt(scanner.next().trim()); } catch (NoSuchElementException e) { System.out.println("Error reading car data: " + e.getMessage()); } } }
RentShop类
import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Scanner; import javax.swing.JFileChooser; public class RentShop { public ArrayList<Vehicle> vehicleList; public RentShop() { vehicleList = new ArrayList<Vehicle>(); } public void storeVehicle(Vehicle vehicle) { vehicleList.add(vehicle); } public void printAllVehicles() { for (Vehicle vehicle : vehicleList) { vehicle.printDetails(); } } public void readDetails() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle("Select Vehicle Data File"); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setAcceptAllFileFilterUsed(false); fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); int result = fileChooser.showOpenDialog(null); if (result == JFileChooser.APPROVE_OPTION) { File selectedFile = fileChooser.getSelectedFile(); try { Scanner scanner = new Scanner(selectedFile); while (scanner.hasNextLine()) { String lineOfText = scanner.nextLine().trim(); System.out.println(lineOfText); Scanner lineScanner = new Scanner(lineOfText); lineScanner.useDelimiter(","); Car car = new Car(); car.readDetails(lineScanner); vehicleList.add(car); lineScanner.close(); } scanner.close(); printAllVehicles(); } catch (FileNotFoundException e) { System.out.println("File not found: " + e.getMessage()); } } } }
验证说明
修改后运行RentShop的readDetails方法,文本文件每行数据会被正确拆分:前6个字段赋值给Vehicle父类,后2个字段赋值给Car子类,printDetails可完整输出所有字段值,包括isConvertible和numOfDoors。
内容的提问来源于stack exchange,提问作者Some dude
相关产品推荐
相关产品推荐

