Java序列化:readFields()超出了readObject()?

Java序列化:readFields()超出了readObject()?,java,serialization,deserialization,obfuscation,objectinputstream,Java,Serialization,Deserialization,Obfuscation,Objectinputstream,ObjectInputStream.readFields()仅在private void readObject(ObjectInputStream)方法中合格 public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException { SerialCallbackContext ctx = curContext; if (ctx == null) { throw new N

ObjectInputStream.readFields()
仅在
private void readObject(ObjectInputStream)
方法中合格

public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException {
  SerialCallbackContext ctx = curContext;
  if (ctx == null) {
    throw new NotActiveException("not in call to readObject");
  }
...
当我无法使用默认序列化来读取对象时(即
ObjectInputStream.defaultReadObject()
),我不希望在所有类中实现
readObject()
方法。在理想情况下,我希望使用
ownDefaultReadObject()
方法从序列化字段(例如通过反射)构造新对象

有什么想法吗


如果有人想知道更多。我的一些类中的字段名被重命名(例如通过模糊处理程序)为a、b、c等。这些类使用默认Java序列化的重命名字段进行序列化。我需要将它们反序列化为原始类(我知道每个类的字段名对;a=>fieldName,b=>age,c=>gender等等)。

要从对象流重命名字段,需要重写的方法是
ObjectInputStream.readClassDescriptor
,它返回一个
ObjectStreamClass

实例
ObjectStreamClass
通过接口的大型不同子集履行两个不同角色之一。为免生疑问,不得复制此设计选择

  • 描述在当前JVM实例中运行的可序列化类的字段。通过
    ObjectStreamClass.lookup
    查找这些实例
  • 描述特定序列化流中表示的可序列化类的字段。这些实例由
    ObjectInputStream.readClassDescriptor
    的实现返回
在覆盖调用
super.readClassDescriptor
中。这将从流中读取数据。如果您感兴趣的是一个类,则将流中的值替换为具有新字段名称的值

如何创建自己的
ObjectStreamClass
?将感兴趣的类的虚拟实例写入
ObjectOutputStream
。您可以将此作为构建的一部分来执行,只需保留二进制数据。使用另一个
ObjectInputStream
读取,并覆盖
readClassDescriptor
以隐藏描述符


ObjectInputStream.defaultReadObject
/
readFields
readObject
(或类似)之外没有任何意义,因为它们依赖于当前的反序列化对象而不是参数。还有其他限制,以防止其他代码调用
defaultReadObject
重写必须保持不变、复制验证、安全检查或类似的字段。

您的愿望是一回事,但您不实现
readObject()
的原因是什么?我不怀疑您的选择,但是,实现将调用委托给自定义处理程序的
readObject()
不是更容易吗?这样,即使您需要在每个类中实现该方法,实现也只是一个方法调用。@EJP 16:我有几百个这样的类。它们可以在将来添加/删除。我不希望开发团队中的任何人想到序列化/反序列化问题。其中一个选项是,我必须使用字节码指令插入(例如Javassist)在构建过程中添加readObject()方法,但我希望使用更简单的解决方案。@biziclop:是的,我正在考虑这个解决方案,但使用字节码指令插入。希望存在一个更容易的办法。@FoxyBOA我想说,可能没有更容易的办法。但这只是基于序列化工作的一般方式的猜测,可能有一个不太可能的钩子可以附加此逻辑。我会编写一些代码来实现这一点,但目前我正在做其他事情。对于原始海报和Java序列化来说,可能有点晚了(我最初把这个答案贴错了问题,因为我是个白痴。)你可以使用反射来分配一个变量,检验我的解决方案