Java:重构后加载保存在硬盘上的对象=>“找不到类”异常:/

Posted

技术标签:

【中文标题】Java:重构后加载保存在硬盘上的对象=>“找不到类”异常:/【英文标题】:Java: load an object saved on hard disk after refactoring => "class not found" exception :/ 【发布时间】:2010-05-12 11:12:46 【问题描述】:

我正在用 java 开发一个应用程序,它使用这个简单的方法定期将对象保存到硬盘上:

public void save(String filename)

    try
    
        FileOutputStream fos = new FileOutputStream(filename);
        GZIPOutputStream gzos = new GZIPOutputStream(fos);
        ObjectOutputStream out = new ObjectOutputStream(gzos);
        out.writeObject(this);
        out.flush();
        out.close();
    
    catch (IOException e)
    
        e.printStackTrace();
    


该对象是 sebbot.learning.DirectPolicySearch 类的一个实例。

问题是,经过一些重构,学习包被重命名为“ballcapture”。现在,当我尝试加载保存的文件时,出现以下异常:

java.lang.ClassNotFoundException: sebbot.learning.DirectPolicySearch

我用来加载文件的方法是:

public static synchronized DirectPolicySearch load(String filename)

    DirectPolicySearch dps = null;
    try
    
        FileInputStream fis = new FileInputStream(filename);
        GZIPInputStream gzis = new GZIPInputStream(fis);
        ObjectInputStream in = new ObjectInputStream(gzis);
        dps = (DirectPolicySearch) in.readObject();
        in.close();
    
    catch (Exception e)
    
        e.printStackTrace();
    

    System.out.println(dps);

    return dps;

谁能帮我解决这个问题? 非常感谢。

【问题讨论】:

【参考方案1】:

类名更改(包括包名更改)是破坏序列化机制的保证方式;它根本不适合与更改名称的类一起使用。

您几乎唯一能做的就是撤消重构以获取最初命名的类,然后将当前版本放入同一个工作区,使用原始类进行反序列化,以编程方式将其内容复制到重构的实例中类,然后将其序列化。

如果您想避免这种麻烦,请考虑使用更强大、更灵活的序列化方法,例如XStream。

【讨论】:

好的,感谢您的详细回答!我想我现在只撤消重构以恢复保存的对象。 你可以在这里看到我的解决方案***.com/questions/10259760/…【参考方案2】:

您的示例说明了为什么序列化不适合长期存储数据:您无法(真正)控制文件格式,并且序列化文件与您的源代码紧密相关 - 如果您更改源代码,你不能再读取以前序列化的文件了。

序列化非常有用的应用是使用 RMI 通过网络连接发送对象,或用于短期临时存储数据(例如用于磁盘上的缓存)。

对于数据的长期存储,请使用其他格式,例如 Michael 建议的 XML 或其他(标准)文件格式。

【讨论】:

【参考方案3】:

我目前面临着类似的问题,即使在我的情况下,除了包名之外,一切都保持不变。我正在考虑将序列化数据作为流读取,并将所有出现的 com.oldPackage.class 替换为 com.newPackage.class。不确定这是否可行,任何 cmets 都会在这里有所帮助。

【讨论】:

这正是我所做的,你可以在这里查看代码:***.com/questions/10259760/…【参考方案4】:

我编写了一个小工具来更改序列化流/文件中的类名/路径。在此处查看代码以及如何使用它:Change the path / class name of a serialized Java object after refactoring

【讨论】:

以上是关于Java:重构后加载保存在硬盘上的对象=>“找不到类”异常:/的主要内容,如果未能解决你的问题,请参考以下文章

如何保存主从应用程序的数据,以便在应用程序后加载?

iOS 14 上的 WKWebView 仅在显着延迟后加载内容

Qt5:下载文件而不保存到硬盘

页面加载后加载mysql查询

更新应用程序后加载错误的 xib

JPA 实体中的预/后加载更新