【问题标题】:Jess and invocation of overloaded Java static methodsJess和重载Java静态方法的调用
【发布时间】:2014-01-04 12:17:32
【问题描述】:

我在从 Jess 调用重载函数时遇到了一些问题,并且得到了意想不到的结果,有时还会出现异常。结果不是太可预测。除其他外,它们似乎取决于有多少重载函数。

是否有可靠的方法来确保调用正确的函数?任何反馈将不胜感激。请耐心等待,因为这会有点长。

我有以下 clp:

(deffunction functionShort (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  
(deffunction functionInteger (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  
(deffunction functionLong (?a1 ?a2 ?a3) (JessOverLoaded.function ?a1 ?a2 ?a3))  

还有 Java 的静态方法:

public static boolean function(Integer arg1, Integer arg2, Integer arg3)  
public static boolean function(Short arg1, Short arg2, Short arg3)  
public static boolean function(Long arg1, Long arg2, Long arg3)   
public static boolean function(Double arg1, Double arg2, Double arg3)  
public static boolean function(Float arg1, Float arg2, Float arg3)  

以下调用都最终调用长版本,function(Long, Long, Long)。 我希望通过将 Java 对象传递给 Jess,它会选择适当的方法来调用。

(functionInteger (FunctionsObjectCreator.createInteger)(FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger))  
(functionShort (FunctionsObjectCreator.createShort)
(FunctionsObjectCreator.createShort) (FunctionsObjectCreator.createShort))  
(functionLong (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong)  (FunctionsObjectCreator.createLong))  

FunctionsObjectCreator.createXYZ() 创建 Integer、Short 和 Long 对象。

这是另一个以 Integer 作为主要类的重载示例:

public static boolean inRange(Integer $impliedParameter, Integer lowerBound, Integer upperBound) {  
    System.out.println("inRange Integer 1");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer lowerBound, Integer upperBound, Integer[] exclusions) {  
    System.out.println("inRange Integer 2");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer[][] listOfRanges, Integer[] exclusions) {  
    System.out.println("inRange Integer 3");  
    return false;  
}  
public static boolean inRange(Integer $impliedParameter, Integer[][] listOfRanges, boolean inclusiveLower, boolean inclusiveUpper, Integer[] exclusions) {  
    System.out.println("inRangeInteger 4");  
    return false;  
}  

为了节省篇幅,我不包含 String、Short、Long、Date、Character 和 Byte 的重载函数。

调用其中一些静态方法的 clp:

(deffunction  functionShort1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(deffunction  functionInteger1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(deffunction  functionLong1 (?a1 ?a2 ?a3)  
(JessOverLoaded.inRange ?a1 ?a2 ?a3))  

(functionInteger1 (FunctionsObjectCreator.createInteger)  (FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger))  
(functionShort1 (FunctionsObjectCreator.createShort) (FunctionsObjectCreator.createShort)  (FunctionsObjectCreator.createShort))  
(functionLong1 (FunctionsObjectCreator.createLong) (FunctionsObjectCreator.createLong)  (FunctionsObjectCreator.createLong))  

上述调用要么未能调用正确的静态方法,要么收到异常。一个这样的例外是:

Jess reported an error in routine JessOverLoaded.inRange  
    while executing (JessOverLoaded.inRange ?a1 ?a2 ?a3)  
    while executing deffunction functionInteger1  
    while executing (functionInteger1 (FunctionsObjectCreator.createInteger)   (FunctionsObjectCreator.createInteger) (FunctionsObjectCreator.createInteger)).
  Message: Error during execution.  
  Program text: ( functionInteger1 ( FunctionsObjectCreator.createInteger ) (   FunctionsObjectCreator.createInteger ) ( FunctionsObjectCreator.createInteger ) )  at line  28 in file src/com/softwareag/rules/functions/JessOverloaded.clp.  
    at jess.Funcall.execute(Funcall.java:346)  
    at jess.FuncallValue.resolveValue(FuncallValue.java:29)  
    at jess.Deffunction.call(Deffunction.java:214)  
    at jess.FunctionHolder.call(FunctionHolder.java:35)  
    at jess.Funcall.execute(Funcall.java:338)  
    at jess.Jesp.parseAndExecuteFuncall(Jesp.java:2309)  
    at jess.Jesp.parseExpression(Jesp.java:459)  
    at jess.Jesp.promptAndParseOneExpression(Jesp.java:309)  
    at jess.Jesp.parse(Jesp.java:288)  
    at jess.Batch.batch(Batch.java:132)  
    at jess.Batch.batch(Batch.java:113)  
    at jess.Batch.batch(Batch.java:75)  
    at jess.Batch.batch(Batch.java:40)  
    at jess.Rete.batch(Rete.java:2791)  
    at com.softwareag.rules.functions.parser.JessFunctions.main(JessFunctions.java:18)  
Caused by: java.lang.IllegalArgumentException: Can't convert '64' to required type   [[Ljava.lang.Double;  
    at jess.RU.valueToObject(RU.java:385)  
    at jess.RU.valueToObject(RU.java:289)  
    at jess.SerializableMD.invoke(SerializableMD.java:62)  
    at jess.MethodFunction.call(StaticMemberImporter.java:102)  
    at jess.FunctionHolder.call(FunctionHolder.java:35)  
    at jess.Funcall.execute(Funcall.java:338)  
    ... 14 more  

【问题讨论】:

  • 您确实意识到 Jess 变量没有类型化?并且这种重载解决方案是 Java 编译器的事情,而不是真正期望通过 Jess 与 Java 的连接在运行时完成,这只会降低性能。 - 这种扩展使用重载有什么理由吗?

标签: methods static call jess


【解决方案1】:

我无法使用每个数字类只有一个参数的简化版本重现该问题。

但是,我对您没有显示的 FunctionsObjectCreator.createInteger 有点怀疑。您是否确定(使用 (java-objectp))这些方法的结果确实是 Java 对象?

尝试使用例如调用您的重载函数

 (call JessOverLoaded function (new Integer 1)(new Integer 2)(new Integer 3))

【讨论】:

  • 不幸的是,我必须处理返回 Byte、Short、Integer、Long、Float、Double 等的 Java 对象,以及它们的数组 [] 和 [][]。 Jess 有这些的内部表示,它必须进行猜测才能找到正确的重载方法。就像您提到的那样,您必须直接从 Jess 实例化 Integer 才能获取 Integer 实例。否则,如果不是所有包装简单 Java 类型的 Java 类,如果从 Java 传递,大多数(如果不是全部)将由 Jess 自己的表示形式表示。
  • 好吧,你来了……你可以确保重载决议选择了正确的方法。这就是你要问的。
【解决方案2】:

老实说,如果您需要处理这类事情,最简单的方法是编写一个 Java 类作为适配器; Java 类可以重命名重载以消除歧义,因此您可以避免整个问题。 Jess 的过载解决方案在复杂情况下可能会失败,而且这不太可能完全解决。你会发现其他动态语言也有类似的问题(尽管在这方面无可否认有些比 Jess 更好。)

Jess 8 稍微好一点,目前处于早期发布阶段,但仍不完美。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多