我的目标:我需要在关机后将应用状态保持在同一状态,让我们说它相当于"暂停"状态。
我的问题:我知道序列化机制不会transient
个变量保存static
变量。但是,我需要在App暂停/关闭后将static
变量保持在完全相同的状态。
Approach-1 :我可以使用我的"文件格式"将静态变量的状态保存到不同的文件中,并将对象序列化为另一个。
a)这是"正常"方法?
方法-2 :如果我延长ObjectInputStream
/ ObjectOutputStream
并覆盖方法readStreamHeader
/ writeStreamHeader
我可以写任何我想要的内容。所以我也可以写我的静态变量。
b)我在做一些我不应该做的事情吗?
这是我编写的测试方法-2的代码,并且接缝工作正常。请注意,我不是Java程序员,因此了解最佳实践非常重要,如果在这种特殊情况下有任何原因。
@SuppressWarnings("serial")
class SequenceIdentifier implements Serializable
{
protected static long seqIdentifier_ = 1L; //This variable MUST NOT be reseted.
private long id_; //Object variable to be serialised.
private SequenceIdentifier(long id)
{ id_ = id;
}
@Override
public String toString()
{ return ("Id : " + id_ + " of " + seqIdentifier_);
}
public static SequenceIdentifier newInstance()
{ return new SequenceIdentifier(seqIdentifier_++);
}
}
final class OOStream extends ObjectOutputStream
{
public OOStream(OutputStream out) throws IOException
{ super(out);
}
@Override
protected void writeStreamHeader() throws IOException
{ super.writeLong(SequenceIdentifier.seqIdentifier_);
}
}
final class OIStream extends ObjectInputStream
{
public OIStream(InputStream in) throws IOException
{ super(in);
}
@Override
protected void readStreamHeader() throws IOException
{ SequenceIdentifier.seqIdentifier_ = super.readLong();
}
}
public class Main
{
public static void dump(ArrayList<SequenceIdentifier> ids)
{
for (SequenceIdentifier id : ids)
System.out.println(id);
}
public static void saveData()
{
ArrayList<SequenceIdentifier> ids = new ArrayList<>(Arrays.asList(SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance()));
try (OOStream oOut = new OOStream(new FileOutputStream("foo.bin")))
{ oOut.writeObject(ids);
} catch (Exception e)
{ System.err.println(e);
}
dump(ids);
}
@SuppressWarnings("unchecked")
public static void loadData()
{
ArrayList<SequenceIdentifier> ids = null;
try (OIStream oIn = new OIStream(new FileInputStream("foo.bin")))
{ ids = (ArrayList<SequenceIdentifier>)oIn.readObject();
} catch (Exception e)
{ System.err.println(e);
}
dump(ids);
}
public static void main(String[] args)
{
saveData();
System.out.println("Counter at this point " + SequenceIdentifier.seqIdentifier_);
SequenceIdentifier.seqIdentifier_ = 0;
loadData();
System.out.println("Counter at this point " + SequenceIdentifier.seqIdentifier_);
}
}
答案 0 :(得分:2)
我会创建一个单独的Memento类,其中包含所有相关数据作为字段并对其进行去序列化。
class MyClassWithStaticFields1 {
private static String field;
}
class MyClassWithStaticFields2 {
private static String field;
}
class StaticMemento {
String field1;
String field2;
}
// serialization
StaticMemento mem = new StaticMemento();
mem.field1 = MyClassWithStaticFields1.field;
mem.field2 = MyClassWithStaticFields2.field;
outputStream.writeObject(mem);
// deserialize
StaticMemento mem = outputStream.readObject();
MyClassWithStaticFields1.setField(mem.field1);
MyClassWithStaticFields2.setField(mem.field2);
所以基本上你的方法-1。
答案 1 :(得分:0)
几种可能性。
static
。readObect()/writeObject()
和defaultReadObject()
的补充defaultWriteObject()
方法,然后序列化/反序列化该字段。writeReplace()/readResolve()
方法,将包含此成员的代理对象替换为非transient
非static
成员。Externalizable
并在相关方法中自行完全控制序列化过程。