Java中的空引用的静态字段
Java中的static
成员( static
字段或static
方法)与它们各自的类而不是这个类的对象相关联。 以下代码尝试访问null
引用上的静态字段。
public class Main { private static final int value = 10; public Main getNull() { return null; } public static void main(String[] args) { Main main=new Main(); System.out.println("value = "+main.getNull().value); } }
虽然main.getNull()
返回null
,但它的工作原理和显示value = 10
。 这个代码是如何工作的?
该行为在Java语言规范中指定:
可以使用空引用来访问类(静态)variables而不引起exception。
更详细地说, 静态字段评估 ,如Primary.staticField
,如下所示(强调我的) – 在你的情况下, Primary = main.getNull()
:
- 主expression式被评估, 结果被丢弃 。 […]
- 如果该字段是非空白的最终字段,则结果是作为主要expression式的types的类或接口中指定的类variables的值。 […]
正如你所说的,因为静态字段不与一个实例相关联。
从实例引用访问静态字段的能力(就像你在做的那样)仅仅是一个语法糖,没有其他含义。
你的代码编译为
main.getNull(); Main.value
当你在编译时使用对象访问静态variables或方法时,它将转换为类名称。 例如:
Main main = null; System.out.println(main.value);
它将打印静态variables值的值,因为在编译时它将被转换为
System.out.println(Main.value);
certificate:
下载反编译器和反编译你的.class文件到.java文件,你可以看到所有的静态方法或variables引用的对象名称自动被类名replace。
-
使用类名访问一个
static
成员是合法的,但是它的no被写为不能使用对象引用variables访问static
成员。 所以它在这里工作。 -
null
对象引用variables被允许访问static
类variables,而不会在编译或运行时抛出exception。
静态variables和方法总是属于类。 所以当我们创build任何对象时,只有非静态variables和方法会随着对象一起堆栈,但是静态驻留在具有类的方法区域中。 这就是为什么当我们尝试访问一个静态variables或方法时,它转换为类名称点variables或方法名称。
请参阅下面的链接了解更多详情。
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html