在我的Java程序中,我有一个名为Car
的类,它是Serializable
。我有另一个名为StaffCar
的类,它是Car
的子类。
然后有一个名为Fleet
的类,它基本上将StaffCar
个对象存储在ArrayList<StaffCar> fleet
中。
然后我有一个课程Main
,其中包含main
方法,该方法包含菜单和switch
处理菜单选项。
我遇到的问题是当我在StaffCar
中添加方法时,即使该方法内部没有 且该方法甚至未被调用,菜单选项是&#39;显示所有汽车信息&#39;,停止工作。
如果我注释掉这个方法,它会再次开始工作。
&#39;显示...&#39;来自printCars()
的{{1}}选项调用Fleet
,其中fleet
加载了序列化文件中的StaffCar
个对象,就像这种方法的存在一样,即使是读取。
Car
import java.util.ArrayList;
import java.io.*;
@SuppressWarnings("serial")
public class Car implements Serializable
{
//attributes for Car
String regNo;
String model;
int mileage;
//default constructor
public Car() throws CarException
{
try
{
setRegNo("??????");
setModel("Unknown");
setMileage(0);
}
catch (CarException c)
{
System.out.println(c.getMessage());
}
}
//setters
public void setRegNo(String regNo) throws CarException
{
if (regNo.isEmpty())
{
throw new CarException("\nInvalid registration number!\n");
}
this.regNo = regNo;
}
public void setModel(String model) throws CarException
{
if (model.isEmpty())
{
throw new CarException("\nModel can't be empty!\n");
}
this.model = model;
}
public void setMileage(int mileage) throws CarException
{
if (mileage < 0)
{
throw new CarException("\nInvalid mileage!");
}
this.mileage = mileage;
}
}
StaffCar
的片段,导致问题的原因
import java.util.ArrayList;
@SuppressWarnings("serial")
public class StaffCar extends Car
{
String staffName;
String availability;
public StaffCar() throws CarException
{
super();
try
{
setAvailability("Available");
setStaffName("");
}
catch (CarException c)
{
System.out.println(c.getMessage());
}
}
public void setStaffName(String staffName)
{
this.staffName = staffName;
}
public void setAvailability(String availability) throws CarException
{
if (availability != "Available" && availability != "Borrowed")
{
throw new CarException("\nInvalid borrow status!\n");
}
this.availability = availability;
}
//this method causing issues, even if empty
/*public void returnCar()
{
}*/
}
Fleet
类
import java.util.ArrayList;
import java.io.*;
public class Fleet
{
//declare container
ArrayList<StaffCar> fleet;
//container to hold regNos
ArrayList<String> regNumbers;
//create constructor
public Fleet()
{
fleet = new ArrayList<StaffCar>();
regNumbers = new ArrayList<String>();
}
//add method
public void addCar(StaffCar car)
{
fleet.add(car);
regNumbers.add(car.regNo);
}
//print all cars' details
public void printCars()
{
for (StaffCar car:fleet)
{
System.out.println(car);
}
}
public void saveAs(String fileName) throws CarException
{
FileOutputStream outputFile;
try
{
outputFile = new FileOutputStream(fileName);
}
catch (IOException io)
{
throw new CarException("\nCannot create " + fileName + "\n");
}
ObjectOutputStream fleetFile;
try
{
fleetFile = new ObjectOutputStream(outputFile);
fleetFile.writeObject(regNumbers);
fleetFile.writeObject(fleet);
fleetFile.close();
}
catch (FileNotFoundException e)
{
throw new CarException("\nCannot create " + fileName + "\n");
}
catch (IOException io)
{
throw new CarException("\nCannot write " + fileName + "\n");
}
}
@SuppressWarnings({ "unchecked", "resource" })
public void open(String fileName) throws CarException
{
FileInputStream inputFile;
try
{
inputFile = new FileInputStream(fileName);
}
catch (FileNotFoundException e)
{
throw new CarException("\nCannot open " + fileName + "\n");
}
ObjectInputStream fleetFile;
try
{
fleetFile = new ObjectInputStream(inputFile);
regNumbers = (ArrayList<String>)fleetFile.readObject();
fleet = (ArrayList<StaffCar>)fleetFile.readObject();
}
catch (IOException io)
{
throw new CarException("\nError reading from " + fileName + "\n");
}
catch (ClassNotFoundException e)
{
throw new CarException("\nError reading from " + fileName + "\n");
}
try
{
fleetFile.close();
}
catch (IOException io)
{
throw new CarException("\nCannot close " + fileName + "\n");
}
}
}
我很抱歉为我倾倒了一堆代码,我知道这是不好的做法,我试图尽可能地压缩代码,但我觉得这是我的所有相关代码问题
就像我说的,我不明白为什么简单添加空方法会导致此问题。
修改
Main
上课
public class Main
{
// new container
static Fleet fleet = new Fleet();
// initialise car object
static StaffCar car;
// programme loop variable
static boolean state = false;
String fileName;
public static void main(String[] args) throws CarException
{
start();
// programme loop
while (!state)
{
try
{
// menu option variable
String option;
//displays menu to user and takes in input
option = Console.askString("Menu:\n1 Add a car\n2 Display all car information\n3 Find a car\n4 Borrow a car\n5 Return a car\n6 Exit\n\n");
//removes white spaces
option = option.trim();
//switch to handle user request
switch (option)
{
//if option 1
case "1":
//call static add car method
addMethod();
break;
//if option 2
case "2":
//call static print car method
displayMethod();
break;
//..option 3
case "3":
//call static find car method
findMethod();
break;
//..option 4
case "4":
borrowMethod();
break;
case "5":
//returnMethod();
break;
case "6":
//call static quit method
quitMethod();
break;
default:
System.out.println();
System.out.println("Invalid option.");
System.out.println();
break;
}
}
catch (CarException c)
{
System.out.println(c.getMessage());
}
}
}
public static void start()
{
try
{
fleet.open("fleet.uwl");
}
catch (CarException e)
{
//System.out.println("\nFile not created yet!\n");
}
}
//static menu method to print cars
public static void displayMethod() throws CarException
{
System.out.println();
//call printCars method
fleet.printCars();
System.out.println();
}
}
答案 0 :(得分:3)
您使用序列化保存了StaffCar的实例,然后更改了StaffCar类,并且无法再次读取已保存的StaffCar。
那是因为,如果你没有在你的类中指定serialVersionUID,JVM会根据类的布局(字段,方法等)为你计算一个。因此,要暂时解决您的问题,请检查读取文件时抛出的IOException,它应该告诉您保存的类的serialVersionUID是什么,并将以下内容添加到您的类中:
=INDEX(Level,-1+MATCH(TRUE,(Level="BR")*ROW(Level)>MATCH($C$1,Level,0),0))
其中XXX是保存对象中的串行版本UID,应在异常堆栈跟踪中提及。
但实际上,您遇到了这些问题,因为您选择使用序列化进行长期存储,这使您的代码很难发展。我不会这样做。相反,我会选择一种不那么脆弱且易于发展的格式,例如JSON或XML。定义文件应包含的内容,并生成包含此数据的JSON / XML文档。然后,无论您未来的casses是什么样子,只要您仍然可以解析JSON / XML,您就能够读取文件并获取保存的数据。