异常处理语句
IRL 提供了报告和处理异常的机制。 发生错误时,规则会抛出异常。 这意味着规则的正常流中断,规则引擎尝试查找异常处理程序,即处理特定类型错误的代码块。 异常处理程序通常执行必要的操作以从错误中恢复。
异常设置
在捕获异常之前,代码必须在某个位置抛出一个异常。 任何 Java™ 代码都可能抛出异常。
throw
表达式是其类型可分配给 Java Throwable
类型或子类的任何类型的表达式。 可以在 API 或规则中指定 throw
表达式。 抛出异常时,可以通过 API 或规则 (使用 try
-catch
-finally
语句或任何 Java 代码) 捕获异常,这将导致 IRL 代码运行。
抛出的异常是 IlrRunTimeException
的 IlrUserRuntimeException
子类型,用于封装 throw
语句抛出的异常。
当 Decision Server 在运行时检测到错误时,将抛出
IlrSystemRuntimeException
。 此类异常无法恢复; 仅用于调试目的。另一方面,可以使用
IlrUserRuntimeException
来重置上下文并重新启动规则。
try-catch-finally 语句
try-catch-finally 语句为:
try
语句标识可能抛出异常的语句块。catch
语句必须与try
语句相关联,并标识可处理特定类型异常的语句块。 如果在 try 块中发生特定类型的异常,那么将运行这些语句。 根据需要,try
语句后面可以有任意数目的语句。 每个语句都处理任何和所有异常,这些异常是括号中列出的类的实例,其任何子类的实例或实现括号中列出的接口的类的实例。finally
语句必须与try
语句相关联,并标识运行的语句块,而不考虑try
块中是否发生错误。finally
语句通常用于在try
语句中的代码之后进行清除。 如果在try
块中发生异常,并且有关联的catch
块来处理该异常,请先控制传输到catch
块,然后再传输到finally
块。
以下是这些语句的一般形式:
try {
statements
}
catch (ExceptionType1 name) {
statements
}
catch (ExceptionType2 name) {
statements
}
...
finally {
statements
}
IRL 允许用于处理多种类型异常的常规异常处理程序。 但是,更专门的异常处理程序可以确定发生的异常类型,并帮助恢复这些错误。 过于一般的处理程序可能会使代码更容易出错,方法是捕获和处理非预期的异常以及处理程序不打算处理的异常。
以下 try
语句演示如何创建异常并将其抛出。
then {
try {
method1(1) ;
System.out.println("Call method1(1) was OK") ;
}
catch ( Exception e ) {
System.out.println("Catch from method1(1) call") ;
}
try {
method1(2) ;
System.out.println("Call method1(2) was OK") ;
}
catch ( Exception e ) {
System.out.println("Catch from method1(2) call") ;
System.out.println("Exception details :-") ;
System.out.println("Message: " + e) ;
}
}
当传递到 method1 的变量不等于 1
时, try
-catch
语句使用来自 Java 类的方法调用来抛出异常。 以下是 method1:
public static void method1(i) throws Exception{
if (i == 1) {
System.out.println("method1 - Things are fine \n") ;
}
else {
System.out.println("method1 - Somethings wrong! \n") ;
throw new Exception("method1 - Its an exception! \n") ;
}
}
规则引擎作用域内的任何规则或 Java 代码抛出的异常由该特定异常的 try-catch
语句捕获。
以下 CatchCustomer
规则提供了一个 try-catch
语句块示例,该语句块能够捕获 ILOG® 规则语言和/或 Java 代码抛出的异常。 此规则使用 Java Exception
类的两个类 Customer
和 Item
以及两个子类 TooHighExpense
和 IsNotMember
。
rule CatchCustomer
{
when {
?c: Customer();
?item: Item();
}
then {
try {
System.out.println("Customer " + ?c.getName() + " wants to buy "
+ " item " + ?item.getLabel() + " for a price of " +
?item.getPrice() + "$");
IsMember(?c);
?c.buy(?item);
}
catch (TooHighExpense ex) {
System.out.println("M/Mrs/Mz " + ?c.getName() + " you have already
bought:");
int j = 0;
for(j = 0; j<?c.getItems().size(); j++) {
java.util.Enumeration ?i = ?c.getItem(j);
System.out.println(" Item: " + ?i.getLabel() + " costs " +
?i.getPrice() + "$");
}
System.out.println("You have at your disposal " + ?c.getBudget() + "$");
System.out.println("The current purchase is not allowed");
}
catch (IsNotMember ex) {
System.out.println("M/Mrs/Mz " + ?c.getName() +
", you are not a member; would you like to
subscribe?");
}
}
}
在此示例中,将为客户提供预算。 不允许客户购买超出已分配预算的商品。 如果客户尝试购买超出预算的商品,那么将抛出 TooHighExpense
异常。 此外,要购买商品,客户必须是成员。 如果非成员尝试购买商品,那么将抛出 IsNotMember
异常。
此处显示了 CatchCustomer
规则中使用的两个 Java 类 IsNotMember
和 TooHighExpense
:
public class IsNotMember extends Exception
{
public IsNotMember(String name){
super();
this.customer = name;
}
public void printStackTrace(PrintWriter s){
s.println("An IsNotMember exception has been caused by customer "
+ customer + ". We are sorry but you can not make a purchase "
+ "without being a member.");
super.printStackTrace(s);
}
String customer;
};
public class TooHighExpense extends Exception
{
public TooHighExpense(String name, int expense, int limit, int price){
super();
this.expense = expense;
this.limit = limit;
this.price = price;
this.customer = name;
}
public void printStackTrace(PrintWriter s){
s.println("A TooHighExpense exception has been caused by customer "
+ customer + ". For this customer, the current expense is " + expense +
" and the authorized budget is " + limit +
". The purchase of the item whose price is " + price
+ " is not allowed.");
super.printStackTrace(s);
}
private int price;
private int limit;
private int expense;
String customer;
};