AviatorScript 完整支持了 java 的异常处理机制,只是做了一些简化:

  1. ## examples/handle_exception.av
  2. try {
  3. throw "an exception";
  4. } catch(e) {
  5. pst(e);
  6. } finally {
  7. p("finally");
  8. }

这段代码有几个特点:

  1. throw 抛出了一个字符串,在 AviatorScript 中,可以 throw 任何东西,非异常的对象都将被转化包装为标准错误 com.googlecode.aviator.exception.StandardError 类的实例。
  2. catch(e) 没有指定异常的类型, AviatorScript 允许不指定异常类型,等价于 catch(Throwable e)
  3. pst(e) 用于打印异常堆栈,也就是 e.printStackTrace() 调用。
  4. AviatorScript 中同样支持 finally 语句,这跟 Java 保持一致。

我们执行上面的例子,将输出:

  1. com.googlecode.aviator.exception.StandardError: an exception
  2. at com.googlecode.aviator.runtime.function.internal.ThrowFunction.call(ThrowFunction.java:30)
  3. at Script_1587611354228_1/303563356.execute0(Unknown Source)
  4. at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
  5. at Lambda_1587611354228_0.call(Unknown Source)
  6. at com.googlecode.aviator.runtime.function.internal.TryCatchFunction.call(TryCatchFunction.java:41)
  7. at Script_1587611354220_0/363771819.execute0(Unknown Source)
  8. at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
  9. at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:92)
  10. at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:144)
  11. at com.googlecode.aviator.example.RunScriptExample.main(RunScriptExample.java:18)
  12. finally

可以看到字符串被包装成了 com.googlecode.aviator.exception.StandardError: an exception 异常。 finally 块也确保被执行了。

throw 和 catch

throw 也可以抛出一个设定的异常类:

  1. throw new IllegalArgumentException("test");

这个语法跟 java 完全一样。catch 同样可以指定要捕获异常的类型:

  1. ## examples/throw_catch.av
  2. try {
  3. throw new IllegalArgumentException("test");
  4. } catch(IllegalArgumentException e) {
  5. p("catch IllegalArgumentException.");
  6. pst(e);
  7. } catch(e) {
  8. p("catch all throwable.");
  9. pst(e);
  10. }

catch(IllegalArgumentException e) 指定了捕获的异常类型,catch 可以罗列多个分支,当异常发生的时候,按照从上到下的顺序匹配,如果匹配到将执行对应的分支语句,我们最后还用 catch(e) 来兜底其他异常:

  1. catch IllegalArgumentException.
  2. java.lang.IllegalArgumentException: test
  3. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  4. at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  5. at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  6. at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  7. at com.googlecode.aviator.runtime.function.internal.NewInstanceFunction.variadicCall(NewInstanceFunction.java:68)
  8. at com.googlecode.aviator.runtime.function.AbstractVariadicFunction.call(AbstractVariadicFunction.java:59)
  9. at Script_1587611593534_1/303563356.execute0(Unknown Source)
  10. at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
  11. at Lambda_1587611593534_0.call(Unknown Source)
  12. at com.googlecode.aviator.runtime.function.internal.TryCatchFunction.call(TryCatchFunction.java:41)
  13. at Script_1587611593527_0/363771819.execute0(Unknown Source)
  14. at com.googlecode.aviator.ClassExpression.executeDirectly(ClassExpression.java:65)
  15. at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:92)
  16. at com.googlecode.aviator.BaseExpression.execute(BaseExpression.java:144)
  17. at com.googlecode.aviator.example.RunScriptExample.main(RunScriptExample.java:18)

catch(e) 不指定异常类型,等价于 catch(Throwable e)

多异常 Catch

从 5.1.0 开始, catch 语句支持单个语句同时捕捉多个异常,当其中一个匹配的时候,就执行分支代码,例如:

  1. ## examples/multi_catch.av
  2. try {
  3. throw new java.io.IOException("test");
  4. } catch(IllegalArgumentException | IllegalStateException | java.io.IOException e) {
  5. pst(e);
  6. }

异常类型之间用 | 隔开,当异常发生的时候,会依次从左到右匹配类型,如果匹配,就执行同一个分支语句。
比如这个例子捕获抛出的 IO异常,并打印堆栈。

finally

finally 语句确保哪怕在异常发生的情况下,最终一定会执行到,整个规则跟 java 是一致,在上文中已有介绍,不再重复。