【问题标题】:What happens when a static method is invoked using a null object reference?当使用空对象引用调用静态方法时会发生什么?
【发布时间】:2010-02-08 17:50:52
【问题描述】:
public class CallingStaticMethod {
public static void method() {
    System.out.println("I am in method");
}
public static void main(String[] args) {
    CallingStaticMethod csm = null;
    csm.method();
   }
}

谁能解释一下上面代码中静态方法是如何被调用的?

【问题讨论】:

  • 每次你写这样的代码都会有一只小猫死去
  • @fuzzy lollipop: :-) @OP: 多年前,我被这种行为咬伤(并且咬得很厉害),原因很简单,我从来没有想过调用类方法使用实例表示法。 (所以我以为我在调用一个实例方法,这就是麻烦开始的地方。)不惜一切代价避免这样做(不是我认为你说你想要这样做;我的看法是你对它为什么不这样做感到困惑' t 编译失败)。

标签: java null static-methods


【解决方案1】:

它已被编译器优化掉,只是因为不需要类的实例。编译器基本上取代了

csm.method();

通过

CallingStaticMethod.method();

一般来说,自己这样做也是一个好习惯。即使是普通的 IDE 也会警告您通过实例访问静态方法,至少 Eclipse 在这里这样做。

【讨论】:

  • 我不这么认为。您可以使用实例语法调用静态方法,无论它是否可以优化。我对这种特殊的配方工作感到有点惊讶,但我认为它是有道理的。 :-)
  • 它可以总是被编译器优化,因为它是静态的。
  • 编译器可以通过多种方式优化代码,使其运行得更快。如果没有实例,您不需要分配/抓取堆等。
  • @Bozho:是的,我想这是另一种看待它的方式。我不会倾向于将其视为优化,但这只是语义上的事情。
  • 我会改写这个答案(但我不会去编辑它;那会很咄咄逼人):我会说“你可以使用实例表示法来调用类方法,即使它不是一个好主意。正如您所发现的,实例根本不重要,甚至可以是null——实例变量的类型决定了类是什么,因此决定了调用什么类方法。避免这样做。”
【解决方案2】:

Java 允许您使用 Class 实例来调用静态方法,但您不应混淆这一允许,就好像该方法将在用于调用它的实例上调用一样。

instance.method();

一样

类.method();

【讨论】:

  • 是的,CallingStaticMethod.method() 使用问题的例子。
  • 就是这样。我的脑海里响起了一个非常遥远的钟声。我似乎记得被它咬过(我使用实例来调用类方法。)
【解决方案3】:

Java 语言规范说引用 get 被评估,然后被丢弃,然后调用静态方法。
15.12.4.1. Compute Target Reference (If Necessary)

当您使用this 引用调用静态方法时,这也是相同的行为。 this 被评估然后被丢弃,然后调用该方法。

规范中甚至还有一个与您的示例类似的示例。

当一个目标引用被计算然后因为调用模式是静态的而被丢弃时,不会检查该引用以查看它是否为空:

class Test1 {
    static void mountain() {
        System.out.println("Monadnock");
    }
    static Test1 favorite(){
        System.out.print("Mount ");
        return null;
    }
    public static void main(String[] args) {
        favorite().mountain();
    }
}

【讨论】:

    【解决方案4】:

    嗯,这完全没问题。静态方法没有被类 A 的对象实例访问。无论您通过类名或引用调用它,编译器都会通过类 java.lang.Class 的实例调用它。

    仅供参考,java 中的每个类(上图中的 CallingStaticMethod)都是类“java.lang.Class”的一个实例。并且无论何时定义一个类,实例都会被创建为 java.lang.Class CallingStaticMethod = new java.lang.Class();

    所以方法在'CallingStaticMethod'上被调用,所以不会出现空指针异常。

    希望这会有所帮助。

    【讨论】:

      【解决方案5】:

      是的我们可以。 只有当我们使用 null 对象调用非静态方法时,它才会抛出 NullPointerException。如果方法是静态的,它将运行;如果方法是非静态的,它将通过 NPE...

      To know more click here...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-25
        • 2014-03-18
        • 2022-06-27
        • 1970-01-01
        • 1970-01-01
        • 2016-07-19
        相关资源
        最近更新 更多