【问题标题】:Static fields on a null reference in JavaJava中空引用上的静态字段
【发布时间】:2012-07-19 18:22:48
【问题描述】:

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 static


【解决方案1】:

Java Language Specification 中指定了该行为:

空引用可用于访问类(静态)变量而不会导致异常。

更详细地说,static field evaluation,例如Primary.staticField 的工作方式如下(强调我的) - 在你的情况下,Primary = main.getNull()

  • 主表达式被计算,结果被丢弃。 [...]
  • 如果该字段是非空白最终字段,则结果是作为主表达式类型的类或接口中指定类变量的值。 [... ]

【讨论】:

  • 如果有人知道为什么会做出这个选择,那会很有趣。
  • @JonofAllTrades 我认为这很明显:在调用空引用时不抛出任何异常是合理的,因为方法是静态的,所以这无关紧要。
  • @JonofAllTrades :真正的问题是为什么选择允许将静态成员作为实例调用......对我来说,这似乎只会导致混乱和可读性降低。
  • @Falanwe:同意,这是我不需要的构造,尽管我主要在不允许使用的 .NET 中工作。我猜你可能想在获得对父类的引用时调用子类的适当静态方法。
  • @Falanwe 这是允许的,但会在 Eclipse 中引发警告:“静态字段 Main.value 应该以静态方式访问”。至少我们这些对警告挑剔的人(比如我)会避免这样的代码。
【解决方案2】:

因为,正如您所说,静态字段与实例无关。

从实例引用访问静态字段的能力(正如您所做的那样)只是一种语法糖,没有其他含义。
您的代码编译为

main.getNull(); 
Main.value

【讨论】:

  • 我称之为语法糖,更像是语法锯末;)
【解决方案3】:

当您在编译时访问带有对象的静态变量或方法时,它会转换为类名。例如:

Main main = null;
System.out.println(main.value);

它会打印静态变量值的值,因为在编译时它会被转换为

System.out.println(Main.value);

证明:

下载反编译器并将你的.class文件反编译成.java文件,你可以看到所有静态方法或变量引用的对象名自动替换为类名。

【讨论】:

    【解决方案4】:
    1. 访问具有类名的static 成员是合法的,但不能 有人写道,不能使用 static 成员 对象引用变量。所以它在这里工作。

    2. 允许null 对象引用变量访问static 类 在编译或运行时不抛出异常的变量 时间。

    【讨论】:

      【解决方案5】:

      静态变量和方法总是属于类。因此,当我们创建任何对象时,只有非静态变量和方法与对象一起进入堆,但静态驻留在类的方法区域中。这就是为什么当我们尝试访问静态变量或方法时,它会转换为类名点变量或方法名。

      详情请参考以下链接。

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

      【讨论】:

        猜你喜欢
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多