Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用空对象引用调用静态方法时会发生什么?_Java_Null_Static Methods - Fatal编程技术网

Java 使用空对象引用调用静态方法时会发生什么?

Java 使用空对象引用调用静态方法时会发生什么?,java,null,static-methods,Java,Null,Static Methods,有人能解释一下在上面的代码中是如何调用静态方法的吗?编译器已经对它进行了优化,只是因为不需要类的实例。编译器基本上替换了 public class CallingStaticMethod { public static void method() { System.out.println("I am in method"); } public static void main(String[] args) { CallingStaticMethod csm = null;

有人能解释一下在上面的代码中是如何调用静态方法的吗?

编译器已经对它进行了优化,只是因为不需要类的实例。编译器基本上替换了

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();
   }
}


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

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

方法()


Class.method()

这完全可以。类A的对象实例未访问静态方法。通过类名或引用调用它,编译器将通过类java.lang.class的实例调用它

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

因此,在“CallingStaticMethod”上调用该方法,因此不会发生空指针异常


希望这有帮助。

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


java语言规范说,对引用get求值,然后丢弃,然后调用静态方法。

这与使用
This
引用调用静态方法时的行为相同
得到评估,然后丢弃,然后调用该方法

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

当由于调用模式是静态的而计算并丢弃目标引用时,不会检查该引用是否为null:


我想不是这样的。您可以使用实例语法调用静态方法,不管它是否可以优化。我对这个特殊的公式的有效性感到有点惊讶,但我认为它是有意义的。:-)编译器总是可以对其进行优化,因为它是静态的。编译器可以通过多种方式优化代码,使其运行更快。如果没有实例,您不需要分配/获取堆等等。@Bozho:是的,我想这是另一种看待它的方式。我不认为这是一种优化,但这只是一种语义上的东西。我会改写这个答案(但我不会去编辑它;那会很急迫):我会说“您可以使用实例表示法来调用类方法,尽管这不是一个好主意。正如您所发现的,实例根本不重要,甚至可以是
null
——是实例变量的类型决定了类是什么,从而决定了调用什么样的类方法。避免这样做。“是的,调用StaticMethod.method()来使用这个问题的示例。就是这样。我的脑海中响起了一个遥远的钟声;我似乎还记得曾经被它咬过一口(我从不使用实例来调用类方法)每次你写这样的代码时,你都会觉得很无聊dies@fuzzy棒棒糖::-)@OP:多年前,我被这种行为咬了一口(而且咬得很厉害),原因很简单,我从来没有想到使用实例符号调用类方法。(所以我以为我调用的是实例方法,这就是问题的根源。)不惜一切代价避免这样做(我不认为你是说你想这样做;我的理解是你对为什么它不会编译失败感到困惑)。
csm.method();
CallingStaticMethod.method();
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();
    }
}