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