为什么“throw null”没有在Java中创建编译错误?

时间:2011-07-06 05:27:26

标签: java exception-handling null

class ThrowNull {
    public static void main(String[] args) {
        throw null;
    }
}

我们知道throw的规则是throw ThrowableInstance;,其中ThrowableInstance必须是Throwable类型的对象或Throwable的子类。

简单类型(如int或char)以及非Throwable类(如String和Object)不能用作异常。 null是一个特殊的Java文字,表示空值。

那么为什么throw null;会在这段代码中编译?

4 个答案:

答案 0 :(得分:54)

根据language specificationthrow语句定义为:

throw Expression

如果Expression评估为null,则会抛出NullPointerException。具体地,

  

如果 Expression 的评估正常完成,产生null值,则会创建并抛出类NullPointerException的实例 V'而不是null

由于NullPointerException扩展RuntimeException,因此它是未经检查的例外。这可以解释为什么没有报告此构造的编译时错误。

答案 1 :(得分:5)

编译器没有检查很多东西,它假设你做了一些它可能不知道的好理由。它试图阻止的是开发人员常犯的错误。

有可能有人认为这是

的好手
throw new NullPointerException();

Integer i = null;
try {
    i.intValue();
} catch (NullPointerException npe) {
    System.err.println("Caught NPE");
    npe.printStackTrace();
}

try {
    throw null;
} catch (NullPointerException npe) {
    System.err.println("Caught NPE");
    npe.printStackTrace();
}

在Java 6 update 38中打印

Caught NPE
java.lang.NullPointerException
    at Main.main(Main.java:9)

答案 2 :(得分:3)

我认为因为Null可以被转换为任何类型的引用。所以在编译时如果你抛出null而不是throwable则没有错。

答案 3 :(得分:2)

一般来说,而不只是扔。任何对象变量都可以赋值为null。所以我们可以看到抛出并不是特例。应该是吗?也许。它一致吗?是。