英文:
Type safety: The expression of type ArrayList needs unchecked conversion to conform to ArrayList<Student>? This throws a ClassCastException
问题
我对Java还很陌生,需要帮助解决我的问题。
我正在尝试编写一个方法来反序列化一个名为Student
的对象。该方法如下:
public void readStudentInfo() {
// 将学生对象反序列化为ArrayList,以便进行比较
try{
FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedStudents = (ArrayList) ois.readObject();
ois.close();
fis.close();
}
catch(IOException ioe){
ioe.printStackTrace();
return;
} catch(ClassNotFoundException c){
System.out.println("Class not found");
c.printStackTrace();
return;
}
for(Student student : deserializedStudents){
System.out.println(student.toString());
}
}
它所使用的Student
类如下:
import java.io.Serializable;
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
// 类属性
private String studentID;
private String rankings;
private char personalityType;
private String conflict;
private String preferences;
// 类构造方法
public Student(String ID){
this.studentID = ID;
}
public Student(String ID, String grades) {
this.studentID = ID;
grades = grades.trim();
this.rankings = grades;
}
public Student(String ID, String ranking, char personality){
this.studentID = ID;
this.rankings = ranking;
this.personalityType = personality;
}
// 访问器方法
public String getStudentID() {
return this.studentID;
}
public String getRankings(){
return this.rankings;
}
public String getPreferences(){
return this.preferences;
}
public char getPersonalityType(){
return this.personalityType;
}
public String getConflict(){
return this.conflict;
}
// 修改器方法
public boolean setPreferences(String pref){
this.preferences = pref;
return true;
}
public boolean setGrades(String grades){
this.rankings = grades;
return true;
}
public boolean setPersonalityType(char pers){
this.personalityType = Character.toUpperCase(pers);
return true;
}
public boolean setConflict(String ids){
this.conflict = ids;
return true;
}
@Override
public String toString(){
return studentID + ";" + rankings + ";" + personalityType + ";" + conflict + ";" + preferences;
}
}
deserializedStudents
ArrayList 在类的顶部初始化如下:ArrayList<Student> deserializedStudents = new ArrayList<>();
由于某种原因,readStudentInfo()
方法中的以下行会产生警告:类型安全性:表达式类型为ArrayList,需要无检查的转换以符合ArrayList
如果我忽略它并运行程序,readStudentInfo()
方法将产生以下错误:异常在线程"main"中发生:java.lang.ClassCastException: class Student cannot be cast to class java.util.ArrayList (Student is in unnamed module of loader 'app'; java.util.ArrayList is in module java.base of loader 'bootstrap')。
可以有人帮助我理解为什么会发生这种情况吗?我已经尝试过几次更改以下行中的类型转换:deserializedStudents = (ArrayList) ois.readObject();
。我还尝试过在程序开头初始化ArrayList时稍微更改一些内容,但是尚未取得任何进展。
澄清:基本思想是我试图将一堆类型为Student的对象反序列化为ArrayList,以便我可以再次使用它们。
请帮忙!
英文:
I'm still quite new to Java and need a hand working out how to get around my problem.
I'm attempting to write a method to deserialize an object that I have called Student
. The method is as follows:
public void readStudentInfo() {
// Desrializes the student objects into an ArrayList for you to compare against
try{
FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
deserializedStudents = (ArrayList) ois.readObject();
ois.close();
fis.close();
}
catch(IOException ioe){
ioe.printStackTrace();
return;
} catch(ClassNotFoundException c){
System.out.println("Class not found");
c.printStackTrace();
return;
}
for(Student student : deserializedStudents){
System.out.println(student.toString());
}
}
The class Student that it works with is as follows:
import java.io.Serializable;
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
// Class Attributes
private String studentID;
private String rankings;
private char personalityType;
private String conflict;
private String preferences;
// Class Constructor
public Student(String ID){
this.studentID = ID;
}
public Student(String ID, String grades) {
this.studentID = ID;
grades = grades.trim();
this.rankings = grades;
}
public Student(String ID, String ranking,char personality){
this.studentID = ID;
this.rankings = ranking;
this.personalityType = personality;
}
// Accessor Methods
public String getStudentID() {
return this.studentID;
}
public String getRankings(){
return this.rankings;
}
public String getPreferences(){
return this.preferences;
}
public char getPersonalityType(){
return this.personalityType;
}
public String getConflict(){
return this.conflict;
}
//Modifier Methods
public boolean setPreferences(String pref){
this.preferences = pref;
return true;
}
public boolean setGrades(String grades){
this.rankings = grades;
return true;
}
public boolean setPersonalityType(char pers){
this.personalityType = Character.toUpperCase(pers);
return true;
}
public boolean setConflict(String ids){
this.conflict = ids;
return true;
}
@Override
public String toString(){
return studentID + ";" + rankings + ";" + personalityType + ";" + conflict + ";" + preferences;
}
}
The ArrayList deserializedStudents
is initiated at the top of the class like so: ArrayList<Student> deserializedStudents = new ArrayList<>();
For some reason the following line of readStudentInfo()
gives this warning : Type safety: The expression of type ArrayList needs unchecked conversion to conform to ArrayList<Student>Java(16777748)
If I ignore it and run the program regardless, the readStudentInfo()
method gives the following error: Exception in thread "main" java.lang.ClassCastException: class Student cannot be cast to class java.util.ArrayList (Student is in unnamed module of loader 'app'; java.util.ArrayList is in module java.base
of loader 'bootstrap')
Can someone please help me to understand why this is happening? I've tried changing the cast in the following line a few times: deserializedStudents = (ArrayList) ois.readObject();
. I've also tried changing things around a little where I initiate the ArrayList at the start of the program, but no luck yet.
Clarification: The basic idea here is that I'm trying to deserialize a bunch of Student type objects into an ArrayList so that I can use them again.
Please help!
答案1
得分: 0
似乎你没有将一个学生对象的列表(它是一个独立的对象)序列化,而是逐个序列化了每个学生对象。因此,你应该要么序列化一个列表,要么逐个反序列化每个学生对象(通过持续调用readObject())。
可以尝试以下方法(使用try-with-resources):
public void readStudentInfo() {
try (FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
List<Student> deserializedStudents = new ArrayList<>();
while (fis.available() > 0) {
deserializedStudents.add((Student) ois.readObject());
}
deserializedStudents.foreach(student -> System.out.println(student));
} catch (IOException | ClassNotFoundException exc) {
exc.printStackTrace();
}
}
英文:
It seems like you did not serialize a list of Students (which is an own object) but Students one by one. Therefore you should either serialize a list or you should deserialize the Students one by one (by continously calling readObject()).
Try this (using try-with-resources):
public void readStudentInfo() {
try (FileInputStream fis = new FileInputStream("student.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
List<Student> deserializedStudents = new ArrayList<>();
while (fis.available() > 0) {
deserializedStudents.add((Student) ois.readObject());
}
deserializedStudents.foreach(student -> System.out.println(student));
} catch(IOException | ClassNotFoundException exc){
exc.printStackTrace();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论