Java : static fields behaviour in different executions

标签 java static

我有这门课:

package scripts;

public class TestStatic {
    public static void main(String[] args) {
        new IncrA().incrStatic();
    }
}

class Static {
    public static int CPT = 0;
}

class IncrA{
    public void incrStatic(){
        for (int i:Range.ints(0,100)){
            System.out.println("Now with "+this.toString()+" : Static.CPT="+Static.CPT);
            Static.CPT++;
            try{
                Thread.sleep(100);
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
        System.out.println("Finally for execution of "+this.toString()+" : Static.CPT="+Static.CPT);
    }
}

现在我从命令行在 Java 中运行类 TestStatic,两次。

javaw -cp ... scripts.TestStatic > 1.txt
javaw -cp ... scripts.TestStatic > 2.txt

我原以为第一次和第二次执行会干扰,并最终获得 Static.CPT == 200 的值,因为我认为 JVM 只会加载一次 Static 类。似乎并非如此。虽然我喜欢它,但我想知道我的这个例子是否足以得出 JVM 完全分离执行的结论。实际上,当我读取我的输出时,我的 IncrA 对象的 hashCode 在两次执行中通常是相同的:

来自 1.txt :

...
Now with scripts.IncrA@19f953d : Static.CPT=72
Now with scripts.IncrA@19f953d : Static.CPT=73
Now with scripts.IncrA@19f953d : Static.CPT=74
Now with scripts.IncrA@19f953d : Static.CPT=75
...

来自 2.txt :

...
Now with scripts.IncrA@19f953d : Static.CPT=72
Now with scripts.IncrA@19f953d : Static.CPT=73
Now with scripts.IncrA@19f953d : Static.CPT=74
Now with scripts.IncrA@19f953d : Static.CPT=75
...

@19f953d 在两个执行中共享。

我在 google 上搜索了有关 static 关键字的深入解释,但没有找到有关这些问题的任何信息。有人可以解释一下或给出一个很好的指示吗?

最佳答案

简短的回答:static 变量仅在单个 JVM 运行中持续存在,因此在您的第一次执行退出后,CPT 设置为 100 的事实实际上丢失了。参见 http://java.sun.com/docs/books/tutorial/java/javaOO/classvars.html有关静态变量与非静态变量的入门知识。简而言之,唯一的区别是静态变量由类的所有实例共享 - 否则,它们的行为基本上相同。

长(呃)的答案是,静态变量有点像实例变量,但对于您的类的 Class 对象。当 JVM 退出时,所有类都被卸载,因此静态变量不再存在,就像该类的任何实例不再存在一样。当您重新启动 Java 进行第二次运行时,它会从您的(编译的)源文件中重新读取您的类的定义,并按照您的要求将 CPT 设置为零。

(在您提到的情况下,同时运行两个 JVM 会导致两个 ClassLoaders 和两个不同的 Class 对象,每个 JVM 一个,因此它们每个都有自己的静态变量的版本。)

如果您想在 Java 执行之间保留任何信息,您需要将其存储在外部某处(例如文件或数据库),并在启动时加载此信息。如果要在运行的 Java 进程之间共享信息,则需要让它们相互通信以共享此信息(例如通过 TCP 连接)。无论所讨论的变量是否为静态,都是如此。

关于Java : static fields behaviour in different executions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1524456/

相关文章:

java - Groovy 枚举中的计算值

java - 是否有任何理由更喜欢 'ClassName.class' 而不是 'this.getClass()' 来获取类对象的实例?

c# - 通用静态字段初始化

c - GCC C 认为我将函数声明为静态的?

c++ - 结构中的静态对象

java - 如何在同一个 bundle (模块)内的另一个服务中使用服务?

java - 如何从我的 Java 应用程序内部运行 JUnit 测试?

java - 是否可以将对象以人类可读的格式发送到文件?

c# - 初始化静态变量时抛出奇怪的异常

c++ - 静态变量的地址值可以与堆分配地址匹配吗?