如何在运行时从类序列化中排除字段?

gap*_*nov 25 java serialization

如何在运行时从序列化过程中排除类字段?编译时有瞬态修饰符,但运行时呢?我的意思是使用ObjectOutputStream的常见java序列化,而不是gson或其他东西.

对不起我想我没解释得对.这是不完全有关序列化的,而是 -serialization.我有一批遗留文件并像这样处理它们:

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;
        }

    }
Run Code Online (Sandbox Code Playgroud)

}

此代码适用于大多数文件,但有些文件会抛出

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)
Run Code Online (Sandbox Code Playgroud)

因为Exit类的版本不同.新版本有新字段.向新字段添加瞬态时错误消失,但另一个文件开始抛出异常(最新文件).

因此,如果我检测到传统的加强文件,我可以在运行时向这些新文件添加瞬态吗?也许反思或什么?

Phi*_*ipp 44

ObjectOutputStream文档说:

对象的默认序列化机制会写入对象的类,类签名以及所有非瞬态和非静态字段的值.对其他对象的引用(瞬态或静态字段除外)也会导致写入这些对象.

因此,当您将变量声明为瞬态时,ObjectOutputStream应该忽略它.确保使用transient关键字而不是@Transient注释.某些ORM框架使用此类注释来标记不应保存在数据库中的字段.它们对于buildin序列化框架毫无意义.

private transient String foo; // Field gets ignored by ObjectOutputStream
@Transient private String bar; // Treated normally by ObjectOutputStream (might mean something for some other framework)
Run Code Online (Sandbox Code Playgroud)