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