実行時にシリアル化プロセスからクラスフィールドを除外する方法は? コンパイル時間には一時的な修飾子がありますが、ランタイムはどうですか? gson などではなく、ObjectOutputStream を使用した一般的な Java シリアル化を意味します。
申し訳ありませんが、私は正しく説明していないと思います。これは正確にはシリアライゼーションではなく、デシリアライゼーションに関するものです。レガシーファイルのバッチがあり、次のように処理します。
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 クラスのバージョンが異なるためです。新しいバージョンには新しいフィールドがあります。新しいフィールドにトランジェントを追加するとエラーが消えますが、別のファイルが例外をスローし始めます (最新のファイル)。
従来のシリアル化されたファイルを検出した場合、実行時にこれらの新しいフィールドに一時的なものを追加できますか? 多分反射か何か?