当我尝试在实例初始化(而不是类初始化)块中抛出异常时,我得到错误:
initializer must be able to complete normally
Run Code Online (Sandbox Code Playgroud)
尽管Java本身就是这样,为什么不允许这样做?
以下示例创建了四个类.A由于ArithmeticException ,该类在实例化期间失败.这可以用和处理catch.B与NullPointerException失败的相同.但是当我尝试自己抛出一个NullPointerException时,因为在C程序中没有编译.当我尝试定义自己的RuntimeException时,我得到了同样的错误D.所以:
我怎么能像Java一样做?
// -*- 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();
}
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*her 15
初始化程序必须能够正常完成
意味着必须有一个不会引发异常的可能代码路径.您的示例无条件抛出,因此被拒绝.在其他示例中,静态分析不足以确定它们也会抛出所有情况.
例如,
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编译,并在运行时抛出
Exception in thread "main" java.lang.ArithmeticException: Heya
at StaticThrow.<init>(StaticThrow.java:3)
at StaticThrow.main(StaticThrow.java:5)
Run Code Online (Sandbox Code Playgroud)
Java旨在具有最小的功能,并且只有在有充分理由的情况下才会添加复杂性.Java不问; 为什么不呢,它问道; 我真的需要支持吗?(有时甚至没有;)
必须将初始化块的代码插入到每个构造函数中,这些构造函数具有编译器知道无法正常完成的块,而编译器发现该条件太难以生成代码.
编译器可以编译这个代码,但它不太可能有用.
在这个特定的情况下它不会帮助你,但知道.....很有用
必须声明已检查的异常,并且无法在静态或实例初始化块中声明已检查的异常.
相反,您可以捕获并处理或包装已检查的异常.(或使用技巧,重新抛出)
| 归档时间: |
|
| 查看次数: |
12918 次 |
| 最近记录: |