我用Java编写了这个程序
public class Why {
public static void test() {
System.out.println("Passed");
}
public static void main(String[] args) {
Why NULL = null;
NULL.test();
}
}
Run Code Online (Sandbox Code Playgroud)
我读到调用一个null对象的方法导致NullPointerException,但上面的程序没有?为什么是这样?我不正确地理解某事吗?
默认情况下,Sun的JVM都懒惰地加载类并且懒惰地初始化(即调用它们的<clinit>方法)它们.考虑以下类,ClinitBomb它Exception在static{}块中抛出一个.
public class ClinitBomb {
static {
explode();
}
private static void explode() {
throw new RuntimeException("boom!");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,考虑如何触发炸弹:
public class Main {
public static void main(String[] args) {
System.out.println("A");
try {
Class.forName("ClinitBomb");
} catch (Exception e) {
e.printStackTrace(System.out);
}
System.out.println("B");
ClinitBomb o2 = new ClinitBomb();
System.out.println("C");
}
}
Run Code Online (Sandbox Code Playgroud)
我们保证爆炸发生在B点之前,因为forName文件说明了这一点; 问题是它是否发生在A点之前(Main加载时).在Sun的JVM中,即使main()包含静态引用ClinitBomb,它也会在A之后发生.
我想要一种方法告诉JVM ClinitBomb一旦初始化就加载并初始化Main(因此炸弹在 A点之前爆炸).一般来说,我想要一种方式来说,"无论何时加载/初始化类X,对任何一个也是如此它引用的Y类."
有没有办法做到这一点?
我遇到了以下代码:
public class TradingSystem {
private static String category = "electronic trading system";
public static void main(String[] args) {
TradingSystem system = null;
System.out.println(system.category);
}
Run Code Online (Sandbox Code Playgroud)
输出:电子交易系统
我很惊讶没有找到NullPointerException!
Q1.它为什么不抛出NullPointerException?
Q2.或者在编译时,由于类别的声明已经static使它替换系统(即对象引用),TradingSystem并且因此基本上TradingSystem.category被称为?
在下面的代码中,我们获得i了null引用的值,尽管a NPE不存在.
public class Test {
static int i = 10;
Test getTest() {
return null;
}
public static void main(String args[]) {
Test t = new Test();
System.out.println(t.getTest());
System.out.println(t.getTest().i);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
null
10
Run Code Online (Sandbox Code Playgroud)