java - 静态字段不更新

标签 java eclipse static

有时我更改了程序中的静态字段,但当程序运行时它仍然会获取旧数据。即使我重建了工作区,它也无法工作。
我使用Eclipse。编译器是否缓存常量值?如何避免这个问题?

Class Container {
    public static String message = new String("original");
}

Class B {
    public void printString() { System.out.println(Container.message); }
}

运行程序时,会打印出“original”。后来我将 Container.message 更改为“已更改”,即使我已经构建了工作区,我的程序仍会打印出“原始”。这对我来说很奇怪。

最佳答案

内联

带有 staticfinal 修饰符的字段由编译器内联。仅具有 static 修饰符的字段不会内联。

我们上两个类

class A {
    static final String X = "test";
}

class B {
    public static void main (String... args) {
        System.out.println(A.X);
    }
}

编译它们,删除A类,然后运行B

javac A.java B.java
rm A.class
java B

它打印测试

来自 staticfinal 字段的字符串已内联到 B 类中。


如果我们从 X 字段中删除 final 修饰符,此示例将失败。

class A {
    static String X = "test";
}

class B {
    public static void main (String... args) {
        System.out.println(A.X);
    }
}

编译它们,删除A类,然后运行B

javac A.java B.java
rm A.class
java B

我们得到

Exception in thread "main" java.lang.NoClassDefFoundError: A
    at B.main(B.java:3)
Caused by: java.lang.ClassNotFoundException: A
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

为了避免过时的内联值问题,请立即重新编译所有源。

类加载器

如果 A 类使用两个不同的类加载器加载,则可能会出现另一个问题。这将产生 A 类的两个副本。更改一个字段中的 static 字段的值对于引用另一个字段中的 static 字段的代码将不可见。

编译器问题

请注意,Eclipse 使用自己的 Java 编译器,其行为与 JDK 编译器不同。

如果你的类(class)有问题。反编译它

javap -c B.class

并检查它是否访问了您想要的字段

3: getstatic     #3                  // Field A.X:Ljava/lang/String;

或者它是内联的

3: ldc           #3                  // String test

关于java - 静态字段不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17463973/

相关文章:

java - 如何将 future 的列从 MySQL 表添加到 ArrayList 并更新我的 jTable?

Java 如何避免字符串索引越界

java - Geb NoClassDefFoundError : geb/error/UnableToLoadException

java - 让多个 Java pop3 客户端与 GMail 一起使用

java - 此标记后应有 VariableDeclaratorId

java - Maven项目构建失败

android - 通过第二个 Activity 从数据库传递 ListView 的项目位置

用于自动递增的Java静态变量(userID)ObjectOutputStream

c# - 实例类的静态成员

java - java中的静态内存是怎么回事?