AviatorScript 完整支持了 java 的异常处理机制,只是做了一些简化:
## examples/handle_exception.avtry {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 exceptionat 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.avtry {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: testat 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.avtry {throw new java.io.IOException("test");} catch(IllegalArgumentException | IllegalStateException | java.io.IOException e) {pst(e);}
异常类型之间用 | 隔开,当异常发生的时候,会依次从左到右匹配类型,如果匹配,就执行同一个分支语句。
比如这个例子捕获抛出的 IO异常,并打印堆栈。
finally
finally 语句确保哪怕在异常发生的情况下,最终一定会执行到,整个规则跟 java 是一致,在上文中已有介绍,不再重复。
