为什么这段代码不会抛出NullPointerException
我刚刚与我的朋友讨论了使用类名调用静态方法,并尝试了这个代码,并期望它在运行时抛出NPE。但事实certificate它是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,但事实并非如此。 你们能不能对这段代码中的执行顺序有所了解。
它的工作原理是重要的是o
字段的编译时类型 。 编译器将o.method()
编译为与o.method()
相同的字节代码。
特别是,如果你有一个扩展One
的类Two
,并且都声明了一个static void method()
,那么
One x = new Two(); x.method(); // calls One.method(), not Two.method()
适用于混淆目的,不太适合可维护性……
method
是静态的,所以它不关心One
实例。
One o = null; o.method();
是相同的:
One.method();
static
方法或变量与类定义本身相关联,而不与类实例相关联 。 因此你的method()
在o
上可用,但理想情况下你应该使用类名本身来调用它:
One.method();//static way of calling static methods
因为你声明static One o;
main
function之外。 你可以尝试在main
函数中声明它,它甚至无法编译…
或者你可以在main
中将它声明为One o = null
,然后它将被编译,但它与One.method()
相同
如果您打算在开发环境中打开代码(例如(Eclipse)),而不是通过在这里显示代码来欺骗人们,而不是以斜体样式提供静态方法的代码格式,那么您会看到checkstyle声称“不要在实例上调用静态方法“。
所以它应该是
One.method()
代替
o.method()
然后很清楚它为什么不崩溃!
- 除了混淆之外,还可以做些什么来保护jar文件?
- ClassLoader getResourceAsStream返回null
- loadClass(String name)和loadClass(String name,boolean resolve)之间的区别
- 如何防止具有META-INF \ services \ javax.xml.transform.TransformerFactory的xalan.jar接管内置在Xalan实现中的JDK 1.6?
- Apache Commons JCI ReloadingClassLoader
- “当一个class级加载”实际意味着什么?
- Java ClassLoader更改
- 加载类和实例化它之间的区别
- 带有来自Jar的多个XML文件的Spring ApplicationContext