我正在编写一个小程序(它是一个ImageJ插件,但问题不是专门与ImageJ相关)而且我有一些问题,很可能是因为我之前从未用Java编程...... < / p>
所以,我有一个矢量矢量,我试图将它保存到一个文件并阅读它。
变量定义为:
Vector <Vector <myROI> > ROIs = new Vector <Vector <myROI> >();
其中myROI
是我之前定义的类。
现在,将矢量写入我使用的文件:
void saveROIs()
{
SaveDialog save = new SaveDialog("Save ROIs...", imp.getTitle(), ".xroi");
String name = save.getFileName();
if (name == null)
return;
String dir = save.getDirectory();
try
{
FileOutputStream fos = new FileOutputStream(dir+name);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(ROIs);
oos.close();
}
catch (Exception e)
{
IJ.log(e.toString());
}
}
这正确地生成了一个二进制文件,其中包含(我想)对象ROIs
。
现在,我使用非常相似的代码来读取文件:
void loadROIs()
{
OpenDialog open = new OpenDialog("Load ROIs...", imp.getTitle(), ".xroi");
String name = open.getFileName();
if (name == null)
return;
String dir = open.getDirectory();
try
{
FileInputStream fin = new FileInputStream(dir+name);
ObjectInputStream ois = new ObjectInputStream(fin);
ROIs = (Vector <Vector <myROI> >) ois.readObject(); // This gives error
ois.close();
}
catch (Exception e)
{
IJ.log(e.toString());
}
}
但是这个功能不起作用。
首先,我收到警告:
warning: [unchecked] unchecked cast found : java.lang.Object
required: java.util.Vector<java.util.Vector<myROI>>
ROIs = (Vector <Vector <myROI> >) ois.readObject();
^
我用Google搜索并看到我可以通过预先@SuppressWarnings("unchecked")
来抑制,但这只会让事情变得更糟,因为我收到错误:
<identifier> expected
ROIs = (Vector <Vector <myROI> >) ois.readObject();
^
在任何情况下,如果我省略@SuppressWarnings
并忽略警告,则不会读取对象并抛出异常
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: myROI
Google再次告诉我myROI
需要implements Serializable
。我尝试将implements Serializable
添加到类定义中,但这还不够。在这种情况下,任何人都可以给我一些关于如何处理的提示吗?另外,如何摆脱类型转换警告?
答案 0 :(得分:1)
myROI的每个属性都必须实现Serializable,或者必须是一个像int这样的简单数据类型。是这样吗?
答案 1 :(得分:1)
warning: [unchecked] unchecked cast found
这是无辜的,应该使用@SuppressWarnings("unchecked")
注释确定。
<identifier> expected
这可能是由添加注释引起的。可能你把它添加到了错误的地方(应该在方法声明之前正确),或者你做了其他导致ROIs
声明消失的事情。
java.io.NotSerializableException: myROI
这意味着由给定的完全限定类名标识的类不可序列化。期望它不可序列化,还有另一个严重的问题:该类不在一个包中。这不一定是当前问题的原因,但这可能会导致未来出现问题,因为无包装类对于包内的类是不可见的。
要使类可序列化,您需要让它implements Serializable
并确保所有字段都可序列化。默认情况下,基元是可序列化的,String
本身已经实现了它,因为您可以在its Javadoc中阅读。如果字段确实由于某种原因无法进行序列化,那么您需要声明transient
并在必要时覆盖private void readObject()
和private void writeObject()
accordingly这样无论如何都可以将不可序列化的对象写入/读取到蒸汽中。至此,您只需要以某种方式保存其状态,以便之后可以恢复完全相同的状态。
E.g。
public class SerializableObject implements Serializable {
private transient UnserializableObject unserializableObject;
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(unserializableObject.getSerializableProperty());
oos.writeObject(unserializableObject.getAnotherSerializableProperty());
// ...
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
unserializableObject = new UnserializableObject();
unserializableObject.setSerializableProperty((SomeSerializableObject) ois.readObject());
unserializableObject.setAnotherSerializableProperty((AnotherSerializableObject) ois.readObject());
// ...
}
}