我会尽可能简明扼要地解释我的问题。我觉得我正在尝试的东西可能本质上是错误的,但不知怎的,我相信它应该有效。所以请随意将这篇文章视为仅仅对序列化机制的澄清。
所以,我有一个由类实现的接口[暗示它们存在于不同的文件中]。
// ----- SomeInterface.java
public interface SomeInterface extends Serializable
{
public void setMsg(String msg);
public void printMsg();
}
// ----- SomeImpl.java
public class SomeImpl implements SomeInterface
{
private String msg;
public void setMsg(String msg)
{
this.msg = msg;
}
public void printMsg()
{
System.out.println("Msg is: " +msg);
}
}
现在我序列化[tt] SomeImpl [/ tt]类的实例:
...
public void SomeMethInSomeClass()
{
FileOutputStream fos = new FileOutputStream(new File("c:/test.ser"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
SomeInterface si = new SomeImpl();
si.setMsg("blah blah");
oos.writeObject(test);
oos.close();
fos.close();
System.out.println("------ done -------");
}
现在在一个单独的项目中,我有一个上面的应用程序的JAR,其中包含接口SomeInterface
,但不包含实现类SomeImpl
。在此应用程序中,如果我尝试执行以下操作:
....
....
public void deserialiserMethod() throws Exception
{
FileInputStream fis = new FileInputStream(new File("c:/test.ser"));
ObjectInputStream ois = new ObjectInputStream(fis);
SomeInterface si = null;
System.out.println("------ reading ----------");
si = (SomeInterface) ois.readObject();
si.printMsg();
System.out.println("------- done ----------");
ois.close();
fis.close();
}
....
...我得到ClassNotFoundException
[SomeImpl
]。现在我知道我的其他项目在其类路径中没有SomeImpl
类。但是不应该转换为父接口的引用来处理那个依赖关系?
感谢您的投入!
答案 0 :(得分:1)
这不是强制转换的问题,这是序列化对象的类类型的问题。如果您的代码从不直接引用SomeImpl
类并不重要,事实仍然是序列化对象仍然属于该类型。
考虑一下 - 如果不是SomeImpl
,反序列化对象将成为哪个类的实例?必须在某处定义字段,如果不在SomeImpl
中,那么在哪里?
即使您要反序列化对象并将其强制转换为java.lang.Object
,您也必须遇到与对象的实际表示形式和运行时类型相同的问题。
答案 1 :(得分:0)
如果反序列化过程无法访问该类,则不能拥有该实例。
如果类未被默认ObjectInputStream
实现使用的“最新”类加载器加载,则可以提供在其他位置加载的其他类。覆盖ObjectInputStream.resolveClass
以提供课程。与RMI一样,您可以通过覆盖ObjectOutputStream.annotateClass
来“注释”流,以指示应该在哪里找到类。