【问题标题】:Reading objects from a file ClassCastException error从文件读取对象 ClassCastException 错误
【发布时间】:2018-05-16 07:45:52
【问题描述】:

我正在尝试将名为 questions 的 Question 对象的 ArrayList 写入文件,然后读取该文件。

我的问题是,当我阅读文件时,它给了我一个错误,上面写着:java.lang.ClassCastException: java.lang.String cannot be cast to Question at Quiz.load

我的问题是,为什么会出现这个问题,我该如何解决?我一直在阅读很多教程,他们只是将对象转换为我所做的类名。我包含了我的保存和加载功能。

测验课内:

将对象写入文件

    ArrayList<Question> questions = new ArrayList<>();
    //filename given by user
    FileOutputStream fos = new FileOutputStream(filename);
    ObjectOutputStream oos = new ObjectOutputStream(fos);

    oos.writeObject(questions);

从文件中读取对象

    ArrayList<Question> readQuestions = new ArrayList<>();
    FileInputStream fis = new FileInputStream(filename);
    ObjectInputStream ois = new ObjectInputStream(fis);

    System.out.print("QUIZ LOADING...");

    readQuestions.add((Question)ois.readObject()); //problem occurs

【问题讨论】:

  • 非常简单。您序列化了一个字符串并试图将其反序列化为一个问题。很明显,这不是为生成文件而实际执行的代码。这段代码除了序列化一个空的 ArrayList 之外什么都不做,这进一步证明了这一点。 进一步通过您的代码序列化 ArrayList 但尝试将其反序列化为一个问题这一事实证明了这一点,这开始没有意义。我只能建议你发布真实的代码。
  • 嗨,EJP,谢谢,我会稍微发布一下代码。我会修改它,因为它也有 GUI 的东西,而且太长了。
  • @EJP 你是说最近的那个吗?我之前发布的那个没有扫描仪和导入,所以我只是添加了那个。完整的代码中有 GUI,自从我使用 NetBeans 的自动生成代码的拖放功能以来,它已经很长时间了。当前代码可以在终端上编译/运行,它仍然显示 ClassCastException
  • 我在问你为什么发布的代码与你所询问的异常的实际产生方式无关。这完全是在浪费每个人的时间。不要这样做。
  • @EJP 我也是这么想的。我将您对“真实代码”的评论误解为“完整代码”,因为代码的 sn-p 并不代表真实代码。我猜你的意思是把问题的相关代码。我将删除不必要的代码。

标签: java file serialization arraylist classcastexception


【解决方案1】:

正如我所说。你正在序列化一个String

 oos.writeObject(questions.toString()); 

然后尝试将其反序列化为 Question,但从未如此:

(Question)in.readObject();

解决方案:

  • 删除.toString() 部分。
  • 反序列化为List&lt;Question&gt;,这才是真正的样子。

【讨论】:

  • 好的,我会试试的。谢谢。
  • 你这样做的时候发生了什么?
【解决方案2】:

您正在序列化一个列表并使用 Question 反序列化它。

改变一下

readQuestions.add((问题)ois.readObject()); //出现问题

有了这个

readQuestions = (ArrayList&lt;Question&gt;) ois.readObject();

进一步说明: 当我尝试这个例子时,我得到了这个错误: java.lang.ClassCastException:java.util.ArrayList 无法转换为 Question 因此,如果您收到带有 String 的 ClassCastException,很可能您也缺少 Question 上的 Serializable 接口。像这样:

class Question implements Serializable {
    String text;

    public Question(String text) {
        this.text = text;
    }
}

添加工作代码:

import java.io.*;
import java.util.ArrayList;

public class ObjectIS {
    public static void main(String[] args) {
        new ObjectIS().save();
        new ObjectIS().load("abcd");
    }

    public void save() {
        try {
            ArrayList<Question> questions = new ArrayList<>();
            questions.add(new Question("what is your name"));
            //filename given by user
            FileOutputStream fos = new FileOutputStream("abcd");
            ObjectOutputStream oos = new ObjectOutputStream(fos);

            oos.writeObject(questions);

            oos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void load(String filename) {
        try {
            ArrayList<Question> readQuestions = new ArrayList<>();
            FileInputStream fis = new FileInputStream(filename);
            ObjectInputStream ois = new ObjectInputStream(fis);

            System.out.print("QUIZ LOADING...");

//            readQuestions.add((Question) ois.readObject()); //problem occurs
            readQuestions = (ArrayList<Question>) ois.readObject();
            System.out.println("ois = " + readQuestions);
            ois.close();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassCastException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }

}

class Question  implements Serializable {
    String text;

    public Question(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("Question{");
        sb.append("text='").append(text).append('\'');
        sb.append('}');
        return sb.toString();
    }
}

【讨论】:

  • 正确,但没有解释报告的实际异常。
  • 我也试过了,我得到了这个新错误:警告:[unchecked] unchecked cast readQuestions = (ArrayList)ois.readObject();必需:ArrayList 找到:对象 1 警告
  • @EJP 编辑了解释,有意义吗?
  • 没有。如果 Question 不可序列化,则会产生不同的异常。不是来自 String 的 ClassCastException。
  • 其实你是对的,当我删除 Serializable 时,我得到了这个错误:java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException:问题。我不确定如何使用 String 获取 ClassCast。 :)
【解决方案3】:

想象你有一个空盒子。你在盒子里放了一个苹果。

然后关闭它,稍后再打开它。现在,你认为在那个盒子里找到一个汉堡包会成功吗?

但这就是你正在做的 - 存储一个字符串并期望找到一个 Question 对象。 jvm 告诉您现实与您的假设不符。

解决方案:要么存储问题对象,要么在读取文件时期望字符串返回。

【讨论】:

  • 对。所以你的意思是,每当我将对象存储在我的 ArrayList 中时,它就存储为一个字符串?当我从文件中读取对象时,我无法将它们作为 Question 对象读取,因为它们存储为 String?
  • @HaiHey 不,他只是说您存储的内容与您尝试阅读的内容不同。唯一将任何内容存储为字符串的人是您,在您的真实代码中,您仍然没有提供。
  • @HaiHey 不。我的意思是:当把苹果放进盒子然后苹果在箱子里。您的代码执行您告诉它执行的操作。它存储字符串对象。不是 Question 对象。
  • @EJP 代码已发布
猜你喜欢
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2011-09-26
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多