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

JAVA-静态变量在程序重新启动时重置,java,static,counter,restart,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;

静态计数器变量有问题。在一个超级类(“卡”)中,我有一个变量,用于计算注册的卡的数量(这是一个票证系统)。它是这样写的:

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

    public Card(int t)   {
        id= ++nextNr;
        next= null;
    }
}
该类实现了Serializable,我使用ObjectStream将卡片写入一个文件

但如果我关闭程序并再次启动,它可以读取文件并确认,然后再次将文件添加到我的cardregistry。但是,超级类中的card计数器变量被重置,我尝试注册的每一张新卡都从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.");
    }
}

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

如果仍要保留静态变量的值,则需要使用
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

}
公共类卡实现可序列化{
private List cardList=new ArrayList();
//接二连三
}
在start first load(反序列化)中,加载
对象。无论何时创建
Card
对象,都将其添加到
Cards
cardList
)并序列化
Cards
对象。

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


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

静态成员未被序列化。它们属于类,而不是正在序列化的类实例。

当程序关闭并重新启动时,static不会保存/保留该值。静态修饰符用作类级变量,其值在任何新对象创建过程中保持不变,并且这些对象也可以通过类级访问该静态值。e、 g

public class A{
public static int val = 0;
public int verify = 0;
public A(){
val++;
}
}

A a = new A();      // val = 1
A b = new A();      // val = 2
A c = new A();      // val = 3

a.verify = A.val;   // val = 3
b.verify = A.val;   // val = 3
c.verify = A.val;   // val = 3

现在,为了保留该静态值,您应该将其保存到某个文件或数据库中,并在应用程序重新启动时,根据需要从那里初始化该静态值。

静态字段
仅在
一个JVM
的范围内,即如果停止执行,它们丢失了它们的
范围和数据。

根据Java规范,静态变量不是实例的一部分,而是类级别的一部分。当您序列化数据时,您只对对象而不是类进行序列化,所以静态数据不会被持久化


重新启动类后重新加载该类时,它将加载变量的默认值。

@Aboutblank阅读问题可能重复的感谢!我在程序的出口处写下了卡id,并在开始时读入,结果成功了!=)我不确定我是否理解序列化卡片和包装器类的最后一点?我只是在程序退出时将数字存储在一个文件中,然后在程序启动时加载它。