为什么这段代码不会抛出NullPointerException

时间:2012-12-06 21:01:25

标签: java static classloader static-methods

我刚刚与我的朋友讨论了使用类名调用静态方法,并尝试了这段代码并期望它在运行时抛出NPE。但结果却是dint。我只是想了解执行顺序。

public class One {

    public static void method() {
        System.out.println("in static one");
    }
}

public class Two {

    static One o;

    public static void main(String[] args) {
        o.method(); // expected NPE here, as o is null
    }
}

我知道静态方法应该用它们的类名调用,我甚至知道当我们用实例调用静态方法时,IDE会给出编译器警告。但是我们也可以通过创建一个实例来调用它们,但是,我从来没有在这里创建过实例,o应该得到它的默认值null,因此调用o.method()应该在运行时抛出一个NPE,但它不会“T。你们能否详细说明这段代码中的执行顺序。

5 个答案:

答案 0 :(得分:6)

method是静态的,因此它不关心One实例。

One o = null;
o.method();

与:

相同
One.method();

答案 1 :(得分:6)

这很有效,因为重要的是o字段的编译时类型。编译器将o.method()编译为与One.method()相同的字节代码。

特别是,如果您的课程Two延伸One,并且都声明了static void method(),那么

One x = new Two();
x.method(); // calls One.method(), not Two.method()

适用于混淆目的,不太适合可维护性......

答案 2 :(得分:0)

static方法或变量与类定义本身相关联,而不与类实例相关联。因此,method()上可以使用o,但理想情况下,您应该使用类名本身来调用它:

     One.method();//static way of calling static methods

答案 3 :(得分:0)

因为您在static One o;函数之外声明了main。您可以尝试在main函数内声明它,甚至无法编译...

或者您可以在One o = null中将其声明为main,然后将对其进行编译,但它与One.method()

相同

答案 4 :(得分:0)

如果您打算在开发环境中打开代码,例如(Eclipse), 而不是通过在这里显示代码来欺骗人们,这确实为斜体样式的静态方法提供代码格式化,那么你会看到checkstyle声称“不要在实例上调用静态方法”。

所以它应该是

One.method()

而不是

o.method()

然后很明显为什么它不会崩溃!