AviatorScript 完整支持了 java 的异常处理机制,只是做了一些简化:
## examples/handle_exception.av
try {
throw "an exception";
} catch(e) {
pst(e);
} finally {
p("finally");
}
这段代码有几个特点:
- throw 抛出了一个字符串,在 AviatorScript 中,可以 throw 任何东西,非异常的对象都将被转化包装为标准错误 com.googlecode.aviator.exception.StandardError 类的实例。
catch(e)
没有指定异常的类型, AviatorScript 允许不指定异常类型,等价于catch(Throwable e)
。pst(e)
用于打印异常堆栈,也就是e.printStackTrace()
调用。- AviatorScript 中同样支持
finally
语句,这跟 Java 保持一致。
我们执行上面的例子,将输出:
com.googlecode.aviator.exception.StandardError: an exception
at com.googlecode.aviator.runtime.function.internal.ThrowFunction.call(ThrowFunction.java:30)
at Script_1587611354228_1/303563356.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
at Lambda_1587611354228_0.call(Unknown Source)
at com.googlecode.aviator.runtime.function.internal.TryCatchFunction.call(TryCatchFunction.java:41)
at Script_1587611354220_0/363771819.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:92)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:144)
at com.googlecode.aviator.example.RunScriptExample.main(RunScriptExample.java:18)
finally
可以看到字符串被包装成了 com.googlecode.aviator.exception.StandardError: an exception
异常。 finally
块也确保被执行了。
throw 和 catch
throw 也可以抛出一个设定的异常类:
throw new IllegalArgumentException("test");
这个语法跟 java 完全一样。catch 同样可以指定要捕获异常的类型:
## examples/throw_catch.av
try {
throw new IllegalArgumentException("test");
} catch(IllegalArgumentException e) {
p("catch IllegalArgumentException.");
pst(e);
} catch(e) {
p("catch all throwable.");
pst(e);
}
catch(IllegalArgumentException e)
指定了捕获的异常类型,catch 可以罗列多个分支,当异常发生的时候,按照从上到下的顺序匹配,如果匹配到将执行对应的分支语句,我们最后还用 catch(e)
来兜底其他异常:
catch IllegalArgumentException.
java.lang.IllegalArgumentException: test
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.googlecode.aviator.runtime.function.internal.NewInstanceFunction.variadicCall(NewInstanceFunction.java:68)
at com.googlecode.aviator.runtime.function.AbstractVariadicFunction.call(AbstractVariadicFunction.java:59)
at Script_1587611593534_1/303563356.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
at Lambda_1587611593534_0.call(Unknown Source)
at com.googlecode.aviator.runtime.function.internal.TryCatchFunction.call(TryCatchFunction.java:41)
at Script_1587611593527_0/363771819.execute0(Unknown Source)
at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:92)
at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:144)
at com.googlecode.aviator.example.RunScriptExample.main(RunScriptExample.java:18)
catch(e)
不指定异常类型,等价于 catch(Throwable e)
。
多异常 Catch
从 5.1.0 开始, catch 语句支持单个语句同时捕捉多个异常,当其中一个匹配的时候,就执行分支代码,例如:
## examples/multi_catch.av
try {
throw new java.io.IOException("test");
} catch(IllegalArgumentException | IllegalStateException | java.io.IOException e) {
pst(e);
}
异常类型之间用 |
隔开,当异常发生的时候,会依次从左到右匹配类型,如果匹配,就执行同一个分支语句。
比如这个例子捕获抛出的 IO异常,并打印堆栈。
finally
finally 语句确保哪怕在异常发生的情况下,最终一定会执行到,整个规则跟 java 是一致,在上文中已有介绍,不再重复。