Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 序列化时如何保存静态变量_Java_Serialization_Static Variables - Fatal编程技术网

Java 序列化时如何保存静态变量

Java 序列化时如何保存静态变量,java,serialization,static-variables,Java,Serialization,Static Variables,我的目标:我需要在关机后将应用程序状态保持在完全相同的状态,假设它相当于“挂起”状态 我的问题:我确实知道序列化机制不会保存瞬态变量,也不会保存静态变量。但是,在应用程序暂停/关闭后,我需要将静态变量保持在完全相同的状态 方法1:我可以使用我的“文件格式”将静态变量的状态保存到不同的文件中,并将对象序列化到不同的文件中 a) 这是“正常”方法吗? 方法2:如果我扩展ObjectInputStream/ObjectOutputStream并覆盖方法readStreamHeader/writeStr

我的目标:我需要在关机后将应用程序状态保持在完全相同的状态,假设它相当于“挂起”状态

我的问题:我确实知道序列化机制不会保存
瞬态
变量,也不会保存
静态
变量。但是,在应用程序暂停/关闭后,我需要将
静态
变量保持在完全相同的状态

方法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_);
    }
}
@SuppressWarnings(“串行”)
类SequenceIdentifier实现可序列化
{
受保护的静态长seqIdentifier_u=1L;//不得重置此变量。
private long id_;//要序列化的对象变量。
专用序列标识符(长id)
{id\=id;
}
@凌驾
公共字符串toString()
{return(“+seqIdentifier\”的“+Id\”);
}
公共静态SequenceIdentifier newInstance()
{返回新的SequenceIdentifier(seqIdentifier_U+);
}   
}
最后一个类OOStream扩展了ObjectOutputStream
{
公共OOStream(OutputStream out)抛出IOException
{super(out);
}   
@凌驾
受保护的void writeStreamHeader()引发IOException
{super.writeLong(SequenceIdentifier.seqIdentifier_u3;);
}
}
最后一个类OIStream扩展了ObjectInputStream
{
公共OIStream(InputStream in)引发IOException
{super(in);
}
@凌驾
受保护的void readStreamHeader()引发IOException
{SequenceIdentifier.seqIdentifier}=super.readLong();
}
}
公共班机
{
公共静态无效转储(ArrayList ID)
{
用于(SequenceIdentifier id:ids)
系统输出打印项次(id);
}
公共静态void saveData()
{
ArrayList ID=新的ArrayList(Arrays.asList(SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance(),
SequenceIdentifier.newInstance());
try(OOStream oOut=newoostream(newfileoutputstream(“foo.bin”))
{oOut.writeObject(id);
}捕获(例外e)
{System.err.println(e);
}       
转储(ids);
}
@抑制警告(“未选中”)
公共静态void loadData()
{
ArrayList ID=null;
try(OIStream oIn=newoistream(newfileinputstream(“foo.bin”))
{ids=(ArrayList)oIn.readObject();
}捕获(例外e)
{System.err.println(e);
}       
转储(ids);
}
公共静态void main(字符串[]args)
{
saveData();
System.out.println(“此时的计数器”+SequenceIdentifier.SequenceIdentifier_);
SequenceIdentifier.seqIdentifier u0;
loadData();
System.out.println(“此时的计数器”+SequenceIdentifier.SequenceIdentifier_);
}
}

我将创建一个单独的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。有几种可能性

  • 使其非静态
  • 编写互补的
    readObect()/writeObject()
    方法,分别调用
    defaultReadObject()
    defaultWriteObject()
    ,然后对字段进行序列化/反序列化
  • 编写互补的
    writeReplace()/readResolve()
    方法,将包含此成员的代理对象替换为非
    暂时的
    静态的
    成员
  • 使对象
    可外部化
    ,并在相关方法中完全控制序列化过程
  • 检查您的需求

  • 我刚刚开始了我的java“冒险”,您能举例说明一下解决方案2和3中的含义吗?请看一下java对象序列化规范和java教程中的序列化章节。