【发布时间】:2013-01-12 23:54:12
【问题描述】:
如何在运行时从序列化过程中排除类字段? 编译时间有 transient 修饰符,但运行时呢? 我的意思是使用 ObjectOutputStream 进行常见的 java 序列化,而不是 gson 之类的。
对不起,我想我解释得不对。这不完全是关于序列化,而是关于de-序列化。我有一批遗留文件并像这样处理它们:
public class Deserialize {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException, IOException {
File file = new File("/home/developer/workspace/DDFS/some.ddf");
HackedObjectInputStream in = new HackedObjectInputStream(new GZIPInputStream(new FileInputStream(file)));
System.out.println("Attempt to open " + file.getAbsolutePath());
Object obj = in.readObject();
in.close();
}
static class HackedObjectInputStream extends ObjectInputStream
{
/**
* Migration table. Holds old to new classes representation.
*/
private static final Map<String, Class<?>> MIGRATION_MAP = new HashMap<String, Class<?>>();
static
{
MIGRATION_MAP.put("DBOBExit", Exit.class);
}
/**
* Constructor.
* @param stream input stream
* @throws IOException if io error
*/
public HackedObjectInputStream(final InputStream stream) throws IOException
{
super(stream);
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException
{
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
for (final String oldName : MIGRATION_MAP.keySet())
{
if (resultClassDescriptor.getName().equals(oldName))
{
resultClassDescriptor = ObjectStreamClass.lookup(MIGRATION_MAP.get(oldName));
}
}
return resultClassDescriptor;
}
}
}
此代码适用于大多数文件,但有些文件会抛出
Exception in thread "main" java.lang.ClassCastException: cannot assign instance of java.awt.Polygon to field Exit.msgbackPt of type java.awt.Point in instance of Exit
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2053)
因为不同版本的 Exit 类。新版本有新领域。 当我将瞬态添加到新字段时错误消失,但另一个文件开始抛出异常(最新文件)。
如果我检测到遗留的序列化文件,我可以在运行时向这些新文件添加瞬态吗? 也许是反射或什么?
【问题讨论】:
-
您需要自己实现
writeObject()和readObject(),或者可能使用Externalizable而不是Serializable,这应该可以让您完全控制该过程:docs.oracle.com/javase/7/docs/platform/serialization/spec/…(和该规范的其他部分。)但请注意,您可能必须以这种方式正确反序列化整个类,并且您必须在反序列化时处理确定在序列化期间编写的字段。 (通过在数据之前写一堆标志等。) -
为什么?另一端会发生什么?
-
查看编辑:我认为您已经完成了工作。如果您想持久化数据并发展其架构,内置序列化是一个非常非常笨拙的选择。
-
我以简单的方式找到了解决方案stackoverflow.com/a/14608062/1085787
标签: java serialization