JAVA - 程序重启时静态变量重置

fuL*_*Man 3 java static counter restart

我有一个静态计数器变量的问题.在超类("卡")中,我有一个变量来计算注册的卡数量(这是一个票务系统).它是这样写的:

public class Card implements Serializable    {
    private int id;
    public static int nextNr= 000;
    Card next;

    public Card(int t)   {
        id= ++nextNr;
        next= null;
    }
}
Run Code Online (Sandbox Code Playgroud)

该类实现了Serializable,我使用ObjectStream将卡写出到文件中.

但是如果我关闭程序并再次启动它,它可以从文件中读取并确认并再次将文件添加到我的cardregistry.但是,超类中的卡计数器变量被重置,我尝试注册的每张新卡都从001开始.我究竟做错了什么?似乎无法在网上找到关于这个特定问题的任何信息.

解决方案: 我使用DataOutputStream在退出时保存它,并使用DataInputStream在启动时读取它.我不知道这是否是最有效的方法,但它有效.非常感谢你的评论,它帮了我很多!!!!

abstract public class Card implements Serializable  {

private int type;
private int cardNr;
private static int nextNr = readCardNr();
Card next;   //COllections or not.. hmmmm

public Card(int t)   {
    cardNr= ++nextNr;
    next= null;
    type = t;
    writeCardNr();
}

public int getType(){
    return type;
}

public void setCardNr(int i) {
    cardNr= i;
}
public int getCardNr()  {
    return cardNr;
}


public static int readCardNr() {        
    try(DataInputStream inn= new DataInputStream(new FileInputStream("KortNummer")))   {
        nextNr= inn.readInt();
        inn.close();
        return nextNr;
    }
    catch(FileNotFoundException fnfe)   {
        skrivMld("Fant ingen tidligere registrerte kort. Starter nytt kortregister.");
        nextNr= 000;
        return nextNr;
    }
    catch(EOFException eofe)    {
        System.out.println("End of file");
    }
    catch(IOException ioe)  {
        skrivMld("Feilmelding: IO Exception");
    }
    return nextNr;
}

public void writeCardNr()    {
    try(DataOutputStream ut= new DataOutputStream(new FileOutputStream("KortNummer"))){
        ut.writeInt(cardNr);
    }
    catch(IOException ioe)  {
        skrivMld("Problem med skriving til fil.");
    }
}
Run Code Online (Sandbox Code Playgroud)

Apu*_*urv 7

序列化不会保留静态变量的值.因此,当再次加载类时,将设置默认值(静态整数为零).要保持该值,请使变量对象保持水平.

如果您仍想保留静态变量的值,则需要使用private void readObject(ObjectInputStream)和提供自定义序列化private void writeObject(ObjectOutputStream)

注意:使用对象序列化静态变量(通过提供自定义序列化)可能会导致问题.

想想这个场景:您创建一个Card对象并对其进行序列化.静态计数器将是1.你创建另一个卡对象并序列化它.静态计数器将是2.所以在你创建10个对象并序列化每个对象.静态计数器将是10.因此,除非您反序列化最后一个对象,否则您将无法获得正确的计数器值.

要避免此问题并仍然存储卡的数量,您可以创建一个包装类 Cards

public class Cards implements Serializable    {
    private List<Card> cardList = new ArrayList<Card>();
    // getter and setter

}
Run Code Online (Sandbox Code Playgroud)

在开始时首先加载(反序列化)Cards对象.每当您创建Card对象时,将其添加到Cards(cardList)并序列化Cards对象.


JB *_*zet 7

计数器是静态的.因此,它不是任何Card 实例的状态的一部分,并且序列化所有卡将不会保存计数器的值.

保存此计数器值,重新加载并明确重置它,或者在启动时从所有反序列化卡中获取最大ID,将计数器重置为此最大值.