8.在Jess中使用Java(下)

8.2.JessJava代码间传递值

本节讲述简单易用的JessJava代码间的输入/输出值的传递机制。

Java的类jess.Rete中提供了下列方法:

public Value store(String name, Value val); 
public Value store(String name, Object val); 
public Value fetch(String name); 
public void clearStorage(); 

 

对应的在Jess中可使用:

(store <name> <value>) 
(fetch <name>) 
(clear-storage) 

 

以上两种方法都以“name”及一个值为参数(在Java中可以是jess.Value对象或一个普通的Java对象;在Jess中可以是任何值),返回同名的任意值,或空(Java中的nullJess中的nil)。利用这些函数可以在JessJava间传递无法用文本表达的数据(当然也可以传递String类型的数据)。下面在Java中建立一个对象,然后在命令行下将其作为一个参数传递给Jess

import jess.*; 
public class ExFetch { 
  public static void main(String[] unused) throws JessException { 
    Rete r = new Rete(); 
    r.store("DIMENSION", new java.awt.Dimension(10, 10)); 
    r.eval("(bind ?list (list dimension (fetch DIMENSION)))"); 
    r.eval("(printout t ?list)"); 
  } 
} 

C:\> java ExFetch 
(dimension <Java-Object:java.awt.Dimension>) 

 

注意:存储一个空值(nullnil)将导致该参数整个从哈希表(hashtable)中删除。clearStorage()clear-storage都可以用于从哈希表中删除数据。

注意:Jess clearJava clear()函数将调用clearStorage(),而resetreset()则不会。因此存储的数据可以由reset()调用。

8.3.Jess中实现Java接口

许多Java库都要求使用者对其进行回收。所谓回收是指实现了某一特殊接口;可以将其传递给库方法(livrary method),同时该回收方法在指定时间被调用。GUI的工作方式如下:回收被称为事件处理者(event-handler)。但Java线程也已该方式运行:由一个新的线程激活的可捕获的接口(Runnable)称为回收。因此在Java编程中一个接口的可实现性相当重要。

Jess支持使用implement函数创建回收。该函数使用简便:只要给定接口名称及deffunction的名称,并调用该函数就能返回一个实现该接口的对象。当任意该接口的一个方法被激活时,第一个参数是接口函数的名称,接下来是所有该接口函数所用的参数。

以实现java.util.Comparator接口为例,该接口用于对大小写敏感的字符串进行排序:

Jess> (import java.util.Comparator) 
Jess> (deffunction compare(?name ?s1 ?s2) 
    (return ((?s1 toUpperCase) compareTo (?s2 toUpperCase)))) 
TRUE 
Jess> (bind ?c (implement Comparator using compare)) 

 

8.3.1.Lambda(l)表达式

调用implement时有一条不错的捷径。不用另外定deffunction,而是定义一个嵌入式的lambda工具。通过该lambda函数可以不用事先命名就定义一个deffunction,而且不用将其添加到Rete引擎中。因此上例可以用lambda表示为:

Jess> (import java.util.Comparator) 
Jess> (bind ?c (implement Comparator using (lambda (?name ?s1 ?s2) 
    (return ((?s1 toUpperCase) compareTo (?s2 toUpperCase)))))) 

 

8.4.工作内存中的Java对象

可以用difinstance使Jess模式匹配到Java对象。同样也可以将Java对象带入Jess中,对此在本文档的其它部分有相关描述。这部分将描述对象在这类转换中所需的最小配置。

Jess可以调用工作内存中任何对象的equalshashCode方法。因此这些方法的正确实现显得十分重要。Java API文档列出了equalshashCode方法的一些重要属性,但这里还是要重申其中最重要的一点(也是最容易忽视的一点):在使用equals时,很可能也必须编写hashCode。因为对于一个类的任意一对实例来说,如果他们的equals返回true,则对于这对实例而言hashCode必须返回同样的值。(For any pair of instances of a class for which equals returns true, hashCode must return the same value for both instances.)如果不遵循该规则,Jess将出现故障,故障的起因就在于处理的元素(fact)中包含了上述违规定义的对象,这些对象存放于元素的插口(slot)中。特别是这类错误会造成没能触发应该触发的规则。

一个值对象(value object)指一种用于表示一个特殊值的类的实例。这类实例通常是不可变的,如整数型、双精度型及字符串型。对于Jess而言,值对象的hashCode()方法返回的是一个常数——例如:其哈希代码(hash code)在类正常操作中保持不变。根据该定义,任何一个不重写(override)默认hashCode()方法的类都可以实现为值对象,因为他们的哈希代码取决于收集(collection)的内容。

Jess中,一个对象只要其在工作内存中时哈希代码保持不变就可称为值对象。这就包含了这样一种情况,在这种情况下该对象包含于任何一个元素的插口中。如果一个对象的哈希代码仅在调用modify时被改变,则仍然是一个值对象。

Jess可以对值对象作特定的假设,从而在模式匹配中极大的提高性能。因为许多类事实上是由Jess广泛定义的值类。Jess现在假设所有对象(除了collection),在默认情况下都是值对象。如果遇到不是值类的类,则必须由使用者在Jess中,使用set-nonvalue-class函数或jess.HashCodeComputer.setNonValueClass()的静态方法;否则将导致未定义(undifined有害)行为。

8.5.设置并读取Java Bean属性

上面曾提到Java对象可以显式的模式匹配于左手边(LHS)规则,但仅限于该对象是Java Bean时。一个Java Bean就是一个Java对象,该对象拥有一系列方法,这些方法都遵循一个简单的命名规则,这些规则用于Java Bean属性的命名。

·一个名为getX的方法返回T并可不带参数的调用;或者,如果T是布尔型的,则命名为isX,也不带参数。

·一个名为setX的方法返回一个空值(void)并接受单个类型为T的参数。

注意:大写也很重要。例如:如果一个方法名为isVisible,则属性名就是visilbe,其属性中的v用小写。只有名字的首字母用大写,这一点很重要。这样就可以很方便的通过Jess中的setget方法使用setget这些属性。

你可能感兴趣的:(java,编程,c,bean,嵌入式)