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。

  1. 使用类名访问一个static成员是合法的,但是它的no被写为不能使用对象引用variables访问static成员。 所以它在这里工作。

  2. null对象引用variables被允许访问static类variables,而不会在编译或运行时抛出exception。

静态variables和方法总是属于类。 所以当我们创build任何对象时,只有非静态variables和方法会随着对象一起堆栈,但是静态驻留在具有类的方法区域中。 这就是为什么当我们尝试访问一个静态variables或方法时,它转换为类名称点variables或方法名称。

请参阅下面的链接了解更多详情。

http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html