为什么不允许在Java实例初始化块中抛出异常? [英] Why is it not allowed to throw an exception in a Java instance initialization block?

查看:71
本文介绍了为什么不允许在Java实例初始化块中抛出异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在实例初始化(而不是类初始化)块中抛出异常时,我收到错误:

When I try to throw an exception in an instance initialization (not class initialization) block I get the error:

initializer must be able to complete normally

为什么不允许Java自己这样做呢?

Why is it not allowed although Java does it itself?

以下示例创建了四个类。由于ArithmeticException,实例化期间类 A 失败。这可以通过 catch 来处理。 B 的情况与NullPointerException失败相同。但是当我尝试在 C 中自己抛出NullPointerException时,程序无法编译。当我尝试在 D 中定义自己的RuntimeException时,我得到了同样的错误。所以:

The following example creates four classes. The class A fails during instantiation because of an ArithmeticException. This can be and handled with a catch. The same for B which fails with a NullPointerException. But when I try to throw a NullPointerException on my own as in C the program does not compile. And I get the same error when I try to define my own RuntimeException as in D. So:

我怎么能像Java一样呢?

How can I do the same as Java does itself?

// -*- compile-command: "javac expr.java && java expr"; -*-

class expr
{
    class A
    {
        int y;
        {{ y = 0 / 0; }}
    }

    class B
    {
        Integer x = null;
        int y;
        {{ y = x.intValue(); }}
    }

    class C
    {
        {{ throw new NullPointerException(); }}
    }

    class Rex extends RuntimeException {}

    class D
    {
        {{ throw new Rex(); }}
    }

    void run ()
    {
        try { A a = new A(); }
        catch (Exception e) { System.out.println (e); }

        try { B b = new B(); }
        catch (Exception e) { System.out.println (e); }

        try { C c = new C(); }
        catch (Exception e) { System.out.println (e); }

        try { D d = new D(); }
        catch (Exception e) { System.out.println (e); }
    }

    public static void main (String argv[])
    {
        expr e = new expr();
        e.run();
    }
}


推荐答案


初始化程序必须能够正常完成

initializer must be able to complete normally

表示必须有一个可能不会抛出的代码路径例外。您的示例无条件抛出,因此被拒绝。在其他示例中,静态分析并不足以确定它们也会抛出所有情况。

means that there must be a possible code path that doesn't throw an exception. Your examples unconditionally throw, and are therefore rejected. In the other examples, the static analysis doesn't go far enough to determine that they also throw in all cases.

例如,

public class StaticThrow {
    static int foo = 0;
    {{ if (Math.sin(3) < 0.5) { throw new ArithmeticException("Heya"); } else { foo = 3; } }}
    public static void main(String[] args) {
        StaticThrow t = new StaticThrow();
        System.out.println(StaticThrow.foo);
    }
}

编译,并在运行时抛出

Exception in thread "main" java.lang.ArithmeticException: Heya
        at StaticThrow.<init>(StaticThrow.java:3)
        at StaticThrow.main(StaticThrow.java:5)

这篇关于为什么不允许在Java实例初始化块中抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆