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
。这段代码是如何工作的?
答案 0 :(得分:92)
该行为在Java Language Specification:
中指定可以使用null引用来访问类(静态)变量,而不会导致异常。
更详细地说,static field evaluation,例如Primary.staticField
的工作原理如下(强调我的) - 在您的情况下,Primary = main.getNull()
:
- 评估主要表达式,结果将被丢弃。 [...]
- 如果该字段是非空白的最终字段,则结果是类或接口中指定的类变量的值,该类是主表达式的类型。 [... ]
答案 1 :(得分:19)
正如您所说,因为静态字段与实例无关。
从实例引用中访问静态字段的能力(正如您所做的那样)仅仅是一种语法糖,没有其他意义。
您的代码编译为
main.getNull();
Main.value
答案 2 :(得分:3)
使用类名访问static
成员是合法的,但是没有
写了一个人无法访问static
成员使用
对象引用变量。所以它在这里工作。
允许null
对象引用变量访问static
类
变量,无需在编译或运行时抛出异常
时间。
答案 3 :(得分:3)
在编译时使用对象访问静态变量或方法时,它会转换为类名。例如:
Main main = null;
System.out.println(main.value);
它将打印静态变量值的值,因为在编译时它将转换为
System.out.println(Main.value);
证明:
下载反编译器并将.class文件反编译为.java文件,您可以看到所有静态方法或变量引用对象名称都自动被类名替换。
答案 4 :(得分:2)
静态变量和方法始终属于类。因此,当我们创建任何对象时,只有非静态变量和方法与对象一起进入堆,但静态驻留在带有类的方法区域中。这就是为什么当我们尝试访问静态变量或方法时,它转换为类名点变量或方法名称。
请参阅以下链接了解更多详情。
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html