内联
static
带有和修饰符的字段final
由编译器内联。只有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
它打印test
。
static
来自,final
字段的字符串被内联到B
类中。
如果我们final
从字段中删除修饰符X
,此示例将失败。
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 编译器不同。
如果你的课程有问题。反编译
javap -c B.class
并检查它是否访问您想要的字段
3: getstatic #3 // Field A.X:Ljava/lang/String;
还是内联
3: ldc #3 // String test