Java…


规则引擎简介

Posted in 未分類·Uncategorized by yanwt on November 10, 2005

Java规则引擎是推�引擎的一�,它起�于基于规则的专家系统。
Java规则引擎将业务决策从应用程åº?代ç ?中分离出æ?¥ï¼Œå¹¶ä½¿ç”¨é¢„定义的语义模å?—编写业务决策。Java规则引擎接å?—æ•°æ?®è¾“入,解释业务规则,并根æ?®è§„则作出业务决策。从这个æ„?义上æ?¥è¯´ï¼Œå®ƒæ˜¯è½¯ä»¶æ–¹æ³•学在”关注点分离”上的一个é‡?è¦?的进展。
JSR-94规范定义了独立于厂商的标准API,开�人员�以通过这个标准的API使用Java规则引擎规范的��产�实现。但值得注�的是,这个规范并没有强制统一规则定义的语法,因此,当需�将应用移�到其他的Java规则引擎实现时,�能需���规则定义。

基于规则的专家系统(RBES)
专家系统是人工智能的一个分支,它模仿人类的推�方�,使用试探性的方法进行推�,并使用人类能�解的术语解释和�明它的推�结论。专家系统有很多分类:神�网络�基于案例推�和基于规则系统等。
规则引擎则是基于规则的专家系统的一部分。为了更深入的了解Java规则引擎,下�简�地介�基于规则的专家系统(RBES)。

RBES的技术架构
RBES包括三部分:Rule Base(knowledge base)�Working Memory(fact base)和Rule Engine(推�引擎)。它们的结构如下所示:

如上图所示,规则引擎包括三部分:Pattern Matcher�Agenda和Execution Engine。Pattern Matcher决定选择执行哪个规则,何时执行规则;Agenda管�PatternMatcher挑选出�的规则的执行次�;Execution Engine负责执行规则和其他动作。

RBES的推�(规则)引擎
和人类的�维相对应,规则引擎存在两者推�方�:演绎法(Forward-Chaining)和归纳法(Backward-Chaining)。演绎法从一个�始的事实出�,�断地应用规则得出结论(或执行指定的动作)。而归纳法则是从�设出�,�断地寻找符��设的事实。
Rete算法是目�效率最高的一个Forward-Chaining推�算法,Drools项目是Rete算法的一个��对象的Java实现。
规则引擎的推�步骤如下:
1. 将�始数�(fact)输入Working Memory。
2. 使用Pattern Matcher比较规则(rule)和数�(fact)。
3. 如果执行规则存在冲�(conflict),��时激活了多个规则,将冲�的规则放入冲�集�。
4. 解决冲�,将激活的规则按顺�放入Agenda。
5. 使用规则引擎执行Agenda中的规则。��步骤2至5,直到执行完毕所有Agenda中的规则。

JSR 94:Java规则引擎API
基于规则编程是一�声明�的编程技术,这�技术让你�以使用试探性的规则而�是过程性的指令�解决问题。规则引擎是一个软件模�,它决定了如何将规则作用于推�数�。在�险业和金��务业都广泛地使用了基于规则的编程技术,当需�在大�的数�上应用��的规则时,规则引擎技术特别有用。
Java规则引擎API由javax.rules包定义,是访问规则引擎的标准�业级API。Java规则引擎API�许客户程�使用统一的方�和��厂商的规则引擎产�交互,就�使用JDBC编写独立于厂商访问��的数�库产�一样。Java规则引擎API包括创建和管�规则集�的机制,在Working Memory中添加,删除和修改对象的机制,以��始化,�置和执行规则引擎的机制。

使用Java规则引擎API
Java规则引擎API把和规则引擎的交互分为两类:管ç?†æ´»åŠ¨å’Œè¿?行时活动。管ç?†æ´»åŠ¨åŒ…æ‹¬å®žä¾‹åŒ–è§„åˆ™å¼•æ“Žå’Œè£…è½½è§„åˆ™ã€‚è€Œè¿?行时活动包括æ“?作Working Memory和执行规则。如果你在J2SE环境中使用Java规则引擎,你å?¯èƒ½éœ€è¦?在代ç ?中执行以上所有的活动。相å??,在J2EE环境中,Java规则引擎的管ç?†æ´»åŠ¨æ˜¯åº”ç”¨æœ?务器的一部分。JSR 94çš„å?‚考实现包括了一个JCA连接器,用于通过JNDI获得一个RuleServiceProvider。

设置规则引擎
Java规则引擎的管�活动阶段开始于查找一个�适的javax.rules.RuleServiceProvider对象,这个对象是应用程�访问规则引擎的入�。在J2EE环境中,你�能�以通过JNDI获得RuleServiceProvider。�则,你�以使用javax.rules.RuleServiceProviderManager类:
javax.rules.RuleServiceProviderManager class:
String implName = “org.jcp.jsr94.ri.RuleServiceProvider”;
Class.forName(implName);
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(implName);
一旦拥有了RuleServiceProvider对象,你å?¯ä»¥èŽ·å¾—ä¸€ä¸ªjavax.rules.admin.RuleAdministrator类。从RuleAdministrator类中,你å?¯ä»¥å¾—到一个RuleExecutionSetProvider,从类å??å?¯ä»¥çŸ¥é?“,它用于创建javax.rules.RuleExecutionSets对象。RuleExecutionSet基本上是一个装入内存的,准备好执行的规则集å?ˆã€‚
包javax.rules.admin包括两个��的RuleExecutionSetProvider类。RuleExecutionSetProvider类本身包括了从Serializable对象创建RuleExecutionSets的方法,因此在规则引擎�于远程�务器的情况下,�然�以使用RuleExecutionSetProvider类,构造器的�数�以通过RMI�传递。�一个类是LocalRuleExecutionSetProvider,包�了其他方法,用于从�Serializable资�(如java.io.Reader�本地文件)创建RuleExectionSets。�设拥有了一个RuleServiceProvider对象,你�以从本地文件rules.xml文件创建一个RuleExectionSet对象。如以下的代�所示:
RuleAdministrator admin = serviceProvider.getRuleAdministrator();
HashMap properties = new HashMap();
properties.put(“name”, “My Rules”);
properties.put(“description”, “A trivial rulebase”);
FileReader reader = new FileReader(“rules.xml”);
RuleExecutionSet ruleSet = null;
try {
LocalRuleExecutionSetProvider lresp =
admin.getLocalRuleExecutionSetProvider(properties);
ruleSet = lresp.createRuleExecutionSet(reader, properties);
} finally {
reader.close();
}
接下æ?¥ï¼Œä½ å?¯ä»¥ä½¿ç”¨RuleAdministrator注册获得的RuleExecutionSet,并给它分é…?一个å??称。在è¿?行时,你å?¯ä»¥ç”¨å?Œä¸€ä¸ªå??称创建一个RuleSession;该RuleSession使用了这个命å??çš„RuleExecutionSet。å?‚è§?下é?¢çš„例å­?:
admin.registerRuleExecutionSet(“rules”, ruleSet, properties);

执行规则引擎
在�行时阶段,你�以��一个RuleSession对象。RuleSession对象基本上是一个装载了特定规则集�的规则引擎实例。你从RuleServiceProvider得到一个RuleRuntime对象,接下�,从javax.rules.RuleRuntime得到RuleSession对象。
RuleSession分为两类:statefulå’Œstateless。它们具有ä¸?å?Œçš„功能。StatefulRuleSessionçš„Working Memory能够在多个方法调用期间ä¿?存状æ€?。你å?¯ä»¥åœ¨å¤šä¸ªæ–¹æ³•调用期间在Working Memory中加入多个对象,然å?Žæ‰§è¡Œå¼•擎,接下æ?¥è¿˜å?¯ä»¥åŠ å…¥æ›´å¤šçš„å¯¹è±¡å¹¶å†?次执行引擎。相å??,StatelessRuleSession类是ä¸?ä¿?存状æ€?的,为了执行它的executeRules方法,你必须为Working Memoryæ??供所有的åˆ?å§‹æ•°æ?®ï¼Œæ‰§è¡Œè§„则引擎,得到一个内容列表作为返回值。
下�的例�中,我们创建一个StatefulRuleSession实例,添加两个对象(一个Integer和一个String)到Working Memory,执行规则,然�得到Working Memory中所有的内容,作为java.util.List对象返回。最�,我们调用release方法清�RuleSession:
RuleRuntime runtime = rsp.getRuleRuntime();
StatefulRuleSession session = (StatefulRuleSession)
runtime.createRuleSession(“rules”, properties,
RuleRuntime.STATEFUL_SESSION_TYPE);
session.addObject(new Integer(1));
session.addObject(“A string”);
session.executeRules();
List results = session.getObjects();
session.release();

集�JSR 94产�实现
支�JSR 94规范的产�实现既有收费的商业产�,也有�费的开�项目。目�最为�熟,功能最强大的商业产�是ILOG公�的JRules,该公�也是JSR 94规范的积�推动者之一。支�JSR 94规范的开�项目目�很少,�有Drools和JLisa项目。值得注�的是,Jess�是开�项目,它�以�费用于学术研究,但用于商业用途则�收费。

JSR 94的产�实现

Java规则引擎商业产�有:
l. ILOG公�的JRules
2. BlazeSoft公�的Blaze
3. Rules4J
4. Java Expert System Shell (JESS)

开�项目的实现包括:
l. Drools项目
2. JLisa项目
3. OFBiz Rule Engine(�支�JSR 94)
4. Mandarax(目��支�JSR 94)

使用Spring集�
集�Java规则引擎的目标是,使用标准的Java规则引擎API�装��的实现,�蔽��的产�实现细节。这样�的好处是,当替���的规则引擎产�时,�以�必修改应用代�。
�装JSR94实现
RuleEngineFacade类�装Java规则引擎,使用ruleServiceProviderUrl和ruleServiceProviderImpl两个�数,�蔽了��产�的�置。代�如下:
public class RuleEngineFacade {
private RuleAdministrator ruleAdministrator;
private RuleServiceProvider ruleServiceProvider;
private LocalRuleExecutionSetProvider ruleSetProvider;
private RuleRuntime ruleRuntime;
// configuration parameters
private String ruleServiceProviderUrl;
private Class ruleServiceProviderImpl;

public void setRuleServiceProviderUrl(String url) {
this.ruleServiceProviderUrl = url;
}
public void setRuleServiceProviderImpl(Class impl) {
this.ruleServiceProviderImpl = impl;
}
public void init() throws Exception {
RuleServiceProviderManager.registerRuleServiceProvider(
ruleServiceProviderUrl, ruleServiceProviderImpl);
ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider(ruleServiceProviderUrl);
ruleAdministrator = ruleServiceProvider.getRuleAdministrator();
ruleSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(null);
}
public void addRuleExecutionSet(String bindUri,InputStream resourceAsStream)
throws Exception {
Reader ruleReader = new InputStreamReader(resourceAsStream);
RuleExecutionSet ruleExecutionSet =
ruleSetProvider.createRuleExecutionSet(ruleReader, null);
ruleAdministrator.registerRuleExecutionSet(bindUri,ruleExecutionSet,null);
}
public StatelessRuleSession getStatelessRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatelessRuleSession) ruleRuntime.createRuleSession(key, null, RuleRuntime.STATELESS_SESSION_TYPE);
}
public StatefulRuleSession getStatefulRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatefulRuleSession) ruleRuntime.createRuleSession(
key, null, RuleRuntime.STATEFUL_SESSION_TYPE);
}
public RuleServiceProvider getRuleServiceProvider() {
return this.ruleServiceProvider;
}
}

�装规则
Ruleç±»å°?装了具体的业务规则,它的输入å?‚æ•°ruleName是定义规则的é…?置文件å??,并ä¾?赖于RuleEngineFacade组件。代ç ?如下:
public class Rule {
private String ruleName;
private RuleEngineFacade engineFacade;

public void init() throws Exception {
InputStream is = Rule.class.getResourceAsStream(ruleName);
engineFacade.addRuleExecutionSet(ruleName, is);
is.close();
}

public void setRuleName(String name) {
this.ruleName = name;
}

public void setEngineFacade(RuleEngineFacade engine) {
this.engineFacade = engine;
}

public StatelessRuleSession getStatelessRuleSession()
throws Exception {
return engineFacade.getStatelessRuleSession(ruleName);
}

public StatefulRuleSession getStatefuleRuleSession()
throws Exception {
return engineFacade.getStatefulRuleSession(ruleName);
}
}

组装规则组件
组装规则的�置文件如下:

http://drools.org/

org.drools.jsr94.rules.RuleServiceProviderImpl

/test/fibonacci.drl

测试用例
最�,我们编写测试用例,代�如下:
public class JSRTest extends TestCase {
ApplicationContext ctx = null;
protected void setUp() throws Exception {
super.setUp();
ctx = new FileSystemXmlApplicationContext(“testrule.xml”);
}
public void testGetRuleSession() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
assertNotNull(rule.getStatefuleRuleSession());
assertNotNull(rule.getStatelessRuleSession());
}
public void testStatelessRule() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
Fibonacci fibonacci = new Fibonacci(50);
List list = new ArrayList();
list.add(fibonacci);
StatelessRuleSession session = rule.getStatelessRuleSession();
session.executeRules(list);
session.release();
}
public void testStatefulRule() throws Exception {
Rule rule = (Rule)ctx.getBean(“fibonacci”);
Fibonacci fibonacci = new Fibonacci(50);
StatefulRuleSession session = rule.getStatefuleRuleSession();
session.addObject(fibonacci);
session.executeRules();
session.release();
}
}

�行测试用例,出现绿�,测试通过。

规则定义语言之间的��
因为JSR 94规范并没有强制统一规则定义的语法,因此,当需�将应用移�到其他的Java规则引擎实现时,�能需���规则定义,如将Drools�有的DRL规则语言转��标准的ruleML,Jess规则语言转��ruleML等。这个工作一般由XSLT转�器�完�。

如何�获音频�输出音频

Posted in 未分類·Uncategorized by yanwt on November 10, 2005

import java.io.*;
import javax.sound.sampled.*;
import java.net.*;

/**
* Title:        VoiceChat
* Description:  输出音频(放音程�)
* Copyright:    Copyright (c) 2001
* Company:
* @author      
* @version 1.0
*/

class Playback implements Runnable {

       final int bufSize = 16384;
       SourceDataLine line;
       Thread thread;
       Socket s;

       Playback(Socket s){//构造器 �得socket以获得网络输入�
         this.s=s;
       }
       public void start() {

           thread = new Thread(this);
           thread.setName(“Playback”);
           thread.start();
       }

       public void stop() {
           thread = null;
       }

       public void run() {

           AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
           BufferedInputStream playbackInputStream;

           try {
             playbackInputStream=new BufferedInputStream(new AudioInputStream(s.getInputStream(),format,2147483647));//�装�音频输出�,如果网络�是�过压缩的需在此加套解压�
           }
           catch (IOException ex) {
               return;
           }

           DataLine.Info info = new DataLine.Info(SourceDataLine.class,format);

           try {
               line = (SourceDataLine) AudioSystem.getLine(info);
               line.open(format, bufSize);
           } catch (LineUnavailableException ex) {
               return;
           }

           byte[] data = new byte[1024];//此处数组的大�跟实时性关系�大,�根�情况进行调整
           int numBytesRead = 0;
           line.start();

           while (thread != null) {
              try{
                 numBytesRead = playbackInputStream.read(data);
                 line.write(data, 0,numBytesRead);
              } catch (IOException e) {
                   break;
               }
           }

           if (thread != null) {
               line.drain();
           }

           line.stop();
           line.close();
           line = null;
       }
}

import java.io.*;
import javax.sound.sampled.*;
import java.net.*;

/**
* Title:        VoiceChat
* Description:  音频��(录音程�)
* Copyright:    Copyright (c) 2001
* Company:
* @author      
* @version 1.0
*/

class Capture implements Runnable {

       TargetDataLine line;
       Thread thread;
       Socket s;
       BufferedOutputStream captrueOutputStream;

       Capture(Socket s){//构造器 �得socket以获得网络输出�
         this.s=s;
       }

       public void start() {

           thread = new Thread(this);
           thread.setName(“Capture”);
           thread.start();
       }

       public void stop() {
           thread = null;
       }

       public void run() {

           try {
             captrueOutputStream=new BufferedOutputStream(s.getOutputStream());//建立输出� 此处�以加套压缩�用�压缩数�
           }
           catch (IOException ex) {
               return;
           }

           AudioFormat format =new AudioFormat(8000,16,2,true,true);//AudioFormat(float sampleRate, int sampleSizeInBits, int channels, boolean signed, boolean bigEndian)
           DataLine.Info info = new DataLine.Info(TargetDataLine.class,format);

           try {
               line = (TargetDataLine) AudioSystem.getLine(info);
               line.open(format, line.getBufferSize());
           } catch (Exception ex) {
               return;
           }

           byte[] data = new byte[1024];//此处的1024�以情况进行调整,应跟下�的1024应��一致
           int numBytesRead=0;
           line.start();

           while (thread != null) {
               numBytesRead = line.read(data, 0,1024);//�数�(1024)的大�直接关系到传输的速度,一般越�越快,
               try {
                 captrueOutputStream.write(data, 0, numBytesRead);//写入网络�
               }
               catch (Exception ex) {
                   break;
               }
           }

           line.stop();
           line.close();
           line = null;

           try {
               captrueOutputStream.flush();
               captrueOutputStream.close();
           } catch (IOException ex) {
               ex.printStackTrace();
           }
       }
}

technorati tags:

如何�获视频

Posted in 未分類·Uncategorized by yanwt on November 10, 2005

package com.borland.samples.welcome;

/**
 * Title:
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:
 * @author
 * @version 1.0
 */
import java.awt.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;

class ImageCanvas extends Canvas{
  private Image image;
  private Dimension prefSize;

  public ImageCanvas(Image image){
    this.image = image;
    calculatePreferredSize();
  }

  public void setImage(Image image){
    this.image = image;
    calculatePreferredSize();
    repaint();
  }

  private void calculatePreferredSize(){
    prefSize = new Dimension(image.getWidth(this),image.getHeight(this));
    System.out.println(image.getWidth(this));
    setSize(prefSize);
  }
  public Dimension getPreferredSize() {
     return prefSize;
  }
  public Dimension getMinimumSize() {
     return prefSize;
  }
  public void update(Graphics g){
     paint(g);
  }
  public void paint(Graphics g){
     g.drawImage(image,0,0,null);
  }
}

class ImageUtils{
  public static Image getScreenImage(){
    Robot robot;
    try {
      robot = new Robot();
    }catch(Exception e) {
      throw new RuntimeException(“unable to construct Robot”);
    }
    Dimension screenDims =Toolkit.getDefaultToolkit().getScreenSize();
    Image screen =robot.createScreenCapture(new Rectangle(450,350,screenDims.width,screenDims.height)).getScaledInstance(400,300,Image.SCALE_SMOOTH);
    MediaTracker tracker =new MediaTracker(new Label());
    tracker.addImage(screen,1);
    try {
      tracker.waitForID(0);
    }catch(InterruptedException e) { /** … */ }
    return screen;
  }
}

public class ScreenCapture extends Frame{
  private ImageCanvas canvas =new ImageCanvas(ImageUtils.getScreenImage());
  public ScreenCapture(){
    add(canvas);
    setSize(400,300);
    setVisible(true);
    Thread imageThread =new UpdateThread();
    imageThread.setDaemon(true);
    imageThread.start();
}
  class UpdateThread extends Thread{
   public void run(){
      while(true){
        try {
          Thread.currentThread().sleep(1000);
        }
        catch (Exception ex) {

        }
        canvas.setImage(ImageUtils.getScreenImage());
        validate();
     }
    }
  }

  public static void main(String[] args){
   new ScreenCapture();

  }
}

technorati tags:

Java çš„å??射机制详解

Posted in 未分類·Uncategorized by yanwt on November 10, 2005

Java çš„å??射机制是使其具有动æ€?特性的é?žå¸¸å…³é”®çš„一ç§?机制,也是在JavaBean 中广泛应用的一ç§?特性。
è¿?用JavaBean 的最常è§?的问题是:根æ?®æŒ‡å®šçš„ç±»å??,类字段å??和所对应的数æ?®ï¼Œå¾—到该类的实例,下é?¢çš„一个例å­?演示了这一实现。
-|Base.java //抽象基类
 |Son1.java //基类扩展1
 |Son2.java //基类扩展2
 |Util.java

/**
 * @author metaphy
 * create 2005-4-14 9:06:56
 * 说明:
 */
(1)Base.java 抽象基类�是一个定义
public abstract class Base {

}
(2)Son1.java /Son2.java 是已�实现的JavaBean
public class Son1 extends Base{
    private int id ;
    private String name ;
   
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
   
    public void son1Method(String s){
        System.out.println(s) ;
    }
}
(3)
public class Son2 extends Base{
    private int id;
    private double salary;
   
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
}
(4)Util.java 演示了如何根æ?®æŒ‡å®šçš„ç±»å??,类字段å??和所对应的数æ?®ï¼Œå¾—到一个类的实例
import java.lang.reflect.Method;

public class Util {
    //此方法的最大好处是没有类å??Son1,Son2 å?¯ä»¥é€šè¿‡å?‚æ•°æ?¥æŒ‡å®šï¼Œç¨‹åº?里é?¢æ ¹æœ¬ä¸?用出现
    public static Base convertStr2ServiceBean(String beanName,String fieldSetter,String paraValue){
        Base base = null ;
        try {
            Class cls = Class.forName(beanName) ;
            base = (Base)cls.newInstance() ;
            Class[] paraTypes = new Class[]{String.class };
            Method method = cls.getMethod(fieldSetter, paraTypes) ;
            String[] paraValues = new String[]{paraValue} ;
            method.invoke(base, paraValues) ;
        } catch (Throwable e) {
            System.err.println(e);
        }
        return base ;
    }
   
   
    public static void main(String[] args){
        Son1 son1 =(Son1) Util.convertStr2ServiceBean(“trying.reflect.Son1″,”setName”,”wang da sha”);
        System.out.println(“son1.getName() :”+son1.getName())  ;
    }
}

//调用结果:
//son1.getName() :wang da sha

谢谢�希望能给大家一点���

ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?ï¼?

附:

//下�这篇文档��于Internet,作者�详

Reflection 是 Java 程åº?å¼€å?‘语言的特å¾?之一,它å…?许è¿?行中的 Java 程åº?对自身进行检查,或者说“自审â€?,并能直接æ“?作程åº?的内部属性。例如,使用它能获得 Java 类中å?„æˆ?员的å??称并显示出æ?¥ã€‚

Java 的这一能力在实际应用中也许用得�是很多,但是在其它的程�设计语言中根本就�存在这一特性。例如,Pascal�C 或者 C++ 中就没有办法在程�中获得函数定义相关的信�。

JavaBean 是 reflection 的实际应用之一,它能让一些工具�视化的�作软件组件。这些工具通过 reflection 动�的载入并�得 Java 组件(类) 的属性。

1. 一个简�的例�

考虑下�这个简�的例�,让我们看看 reflection 是如何工作的。

import java.lang.reflect.*;
public class DumpMethods {
   public static void main(String args[]) {
       try {
           Class c = Class.forName(args[0]);
           Method m[] = c.getDeclaredMethods();
           for (int i = 0; i                System.out.println(m[i].toString());
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

按如下语�执行:

java DumpMethods java.util.Stack

它的结果输出为:

public java.lang.Object java.util.Stack.push(java.lang.Object)

public synchronized java.lang.Object java.util.Stack.pop()

public synchronized java.lang.Object java.util.Stack.peek()

public boolean java.util.Stack.empty()

public synchronized int java.util.Stack.search(java.lang.Object)

这样就列出了java.util.Stack 类的å?„方法å??以å?Šå®ƒä»¬çš„é™?制符和返回类型。

这个程åº?使用 Class.forName 载入指定的类,然å?Žè°ƒç”¨ getDeclaredMethods æ?¥èŽ·å?–这个类中定义了的方法列表。java.lang.reflect.Methods 是用æ?¥æ??è¿°æŸ?个类中å?•个方法的一个类。

2.开始使用 Reflection

用于 reflection 的类,如 Method,å?¯ä»¥åœ¨ java.lang.relfect 包中找到。使用这些类的时候必须è¦?é?µå¾ªä¸‰ä¸ªæ­¥éª¤ï¼šç¬¬ä¸€æ­¥æ˜¯èŽ·å¾—ä½ æƒ³æ“?作的类的 java.lang.Class 对象。在è¿?行中的 Java 程åº?中,用 java.lang.Class ç±»æ?¥æ??述类和接å?£ç­‰ã€‚

下�就是获得一个 Class 对象的方法之一:

Class c = Class.forName(“java.lang.String”);

这�语�得到一个 String 类的类对象。还有�一�方法,如下�的语�:

Class c = int.class;

或者

Class c = Integer.TYPE;

它们�获得基本类型的类信�。其中�一�方法中访问的是基本类型的�装类 (如 Integer) 中预先定义好的 TYPE 字段。

第二步是调用诸如 getDeclaredMethods 的方法,以�得该类中定义的所有方法的列表。

一旦�得这个信�,就�以进行第三步了——使用 reflection API ��作这些信�,如下�这段代�:

Class c = Class.forName(“java.lang.String”);

Method m[] = c.getDeclaredMethods();

System.out.println(m[0].toString());

它将以文本方�打�出 String 中定义的第一个方法的原型。

在下é?¢çš„例å­?中,这三个步骤将为使用 reflection 处ç?†ç‰¹æ®Šåº”用程åº?æ??供例è¯?。

模拟 instanceof �作符

得到类信�之�,通常下一个步骤就是解决关于 Class 对象的一些基本的问题。例如,Class.isInstance 方法�以用于模拟 instanceof �作符:

class A {
}

public class instance1 {
   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“A”);
           boolean b1 = cls.isInstance(new Integer(37));
           System.out.println(b1);
           boolean b2 = cls.isInstance(new A());
           System.out.println(b2);
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

在这个例�中创建了一个 A 类的 Class 对象,然�检查一些对象是�是 A 的实例。Integer(37) �是,但 new A() 是。

3.找出类的方法

找出一个类中定义了些什么方法,这是一个�常有价值也�常基础的 reflection 用法。下�的代�就实现了这一用法:

import java.lang.reflect.*;

public class method1 {
   private int f1(Object p, int x) throws NullPointerException {
       if (p == null)
           throw new NullPointerException();
       return x;
   }

   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“method1″);
           Method methlist[] = cls.getDeclaredMethods();
           for (int i = 0; i                Method m = methlist[i];
               System.out.println(“name = ” + m.getName());
               System.out.println(“decl class = ” + m.getDeclaringClass());
               Class pvec[] = m.getParameterTypes();
               for (int j = 0; j                    System.out.println(“param #” + j + ” ” + pvec[j]);
               Class evec[] = m.getExceptionTypes();
               for (int j = 0; j                    System.out.println(“exc #” + j + ” ” + evec[j]);
               System.out.println(“return type = ” + m.getReturnType());
               System.out.println(“—–”);
           }
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

这个程åº?首先å?–å¾— method1 类的æ??述,然å?Žè°ƒç”¨ getDeclaredMethods æ?¥èŽ·å?–一系列的 Method 对象,它们分别æ??述了定义在类中的æ¯?一个方法,包括 public 方法ã€?protected 方法ã€?package 方法和 private 方法等。如果你在程åº?中使用 getMethods æ?¥ä»£æ›¿ getDeclaredMethods,你还能获得继承æ?¥çš„å?„个方法的信æ?¯ã€‚

å?–得了 Method 对象列表之å?Žï¼Œè¦?显示这些方法的å?‚数类型ã€?异常类型和返回值类型等就ä¸?难了。这些类型是基本类型还是类类型,都å?¯ä»¥ç”±æ??述类的对象按顺åº?给出。

输出的结果如下:

name = f1

decl class = class method1

param #0 class java.lang.Object

param #1 int

exc #0 class java.lang.NullPointerException

return type = int

—–

name = main

decl class = class method1

param #0 class [Ljava.lang.String;

return type = void

-----

4.获�构造器信�

获�类构造器的用法与上述获�方法的用法类似,如:

import java.lang.reflect.*;

public class constructor1 {
   public constructor1() {
   }

   protected constructor1(int i, double d) {
   }

   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“constructor1″);
           Constructor ctorlist[] = cls.getDeclaredConstructors();
           for (int i = 0; i                Constructor ct = ctorlist[i];
               System.out.println(“name = ” + ct.getName());
               System.out.println(“decl class = ” + ct.getDeclaringClass());
               Class pvec[] = ct.getParameterTypes();
               for (int j = 0; j                    System.out.println(“param #” + j + ” ” + pvec[j]);
               Class evec[] = ct.getExceptionTypes();
               for (int j = 0; j                    System.out.println(“exc #” + j + ” ” + evec[j]);
               System.out.println(“—–”);
           }
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

这个例�中没能获得返回类型的相关信�,那是因为构造器没有返回类型。

这个程��行的结果是:

name = constructor1

decl class = class constructor1

—–

name = constructor1

decl class = class constructor1

param #0 int

param #1 double

—–

5.获�类的字段(域)

找出一个类中定义了哪些数�字段也是�能的,下�的代�就在干这个事情:

import java.lang.reflect.*;

public class field1 {
   private double d;
   public static final int i = 37;
   String s = “testing”;

   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“field1″);
           Field fieldlist[] = cls.getDeclaredFields();
           for (int i = 0; i                Field fld = fieldlist[i];
               System.out.println(“name = ” + fld.getName());
               System.out.println(“decl class = ” + fld.getDeclaringClass());
               System.out.println(“type = ” + fld.getType());
               int mod = fld.getModifiers();
               System.out.println(“modifiers = ” + Modifier.toString(mod));
               System.out.println(“—–”);
           }
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

这个例å­?å’Œå‰?é?¢é‚£ä¸ªä¾‹å­?é?žå¸¸ç›¸ä¼¼ã€‚例中使用了一个新东西 Modifier,它也是一个 reflection 类,用æ?¥æ??述字段æˆ?员的修饰语,如“private intâ€?。这些修饰语自身由整数æ??述,而且使用 Modifier.toString æ?¥è¿”回以“官方â€?顺åº?排列的字符串æ??è¿° (如“staticâ€?在“finalâ€?之å‰?)。这个程åº?的输出是:

name = d

decl class = class field1

type = double

modifiers = private

—–

name = i

decl class = class field1

type = int

modifiers = public static final

—–

name = s

decl class = class field1

type = class java.lang.String

modifiers =

—–

和获�方法的情况一下,获�字段的时候也�以��得在当�类中申明了的字段信� (getDeclaredFields),或者也�以�得父类中定义的字段 (getFields) 。

6.æ ¹æ?®æ–¹æ³•çš„å??ç§°æ?¥æ‰§è¡Œæ–¹æ³•

文本到这里,所举的例å­?无一例外都与如何获å?–类的信æ?¯æœ‰å…³ã€‚我们也å?¯ä»¥ç”¨ reflection æ?¥å?šä¸€äº›å…¶å®ƒçš„事情,比如执行一个指定了å??称的方法。下é?¢çš„示例演示了这一æ“?作:

import java.lang.reflect.*;
public class method2 {
   public int add(int a, int b) {
       return a + b;
   }
   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“method2″);
           Class partypes[] = new Class[2];
           partypes[0] = Integer.TYPE;
           partypes[1] = Integer.TYPE;
           Method meth = cls.getMethod(“add”, partypes);
           method2 methobj = new method2();
           Object arglist[] = new Object[2];
           arglist[0] = new Integer(37);
           arglist[1] = new Integer(47);
           Object retobj = meth.invoke(methobj, arglist);
           Integer retval = (Integer) retobj;
           System.out.println(retval.intvalue());
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

å?‡å¦‚一个程åº?在执行的æŸ?处的时候æ‰?知é?“需è¦?执行æŸ?个方法,这个方法的å??称是在程åº?çš„è¿?行过程中指定的 (例如,JavaBean å¼€å?‘环境中就会å?šè¿™æ ·çš„事),那么上é?¢çš„程åº?演示了如何å?šåˆ°ã€‚

上例中,getMethod 用于查找一个具有两个整型å?‚数且å??为 add 的方法。找到该方法并创建了相应的 Method 对象之å?Žï¼Œåœ¨æ­£ç¡®çš„对象实例中执行它。执行该方法的时候,需è¦?æ??供一个å?‚数列表,这在上例中是分别包装了整数 37 å’Œ 47 的两个 Integer 对象。执行方法的返回的å?Œæ ·æ˜¯ä¸€ä¸ª Integer 对象,它å°?装了返回值 84。

7.创建新的对象

对于构造器,则�能�执行方法那样进行,因为执行一个构造器就�味�创建了一个新的对象 (准确的说,创建一个对象的过程包括分�内存和构造对象)。所以,与上例最相似的例�如下:

import java.lang.reflect.*;

public class constructor2 {
   public constructor2() {
   }

   public constructor2(int a, int b) {
       System.out.println(“a = ” + a + ” b = ” + b);
   }

   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“constructor2″);
           Class partypes[] = new Class[2];
           partypes[0] = Integer.TYPE;
           partypes[1] = Integer.TYPE;
           Constructor ct = cls.getConstructor(partypes);
           Object arglist[] = new Object[2];
           arglist[0] = new Integer(37);
           arglist[1] = new Integer(47);
           Object retobj = ct.newInstance(arglist);
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

根�指定的�数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这�方法�以在程��行时动�地创建对象,而�是在编译的时候创建对象,这一点�常有价值。

8.改�字段(域)的值

reflection 的还有一个用处就是改å?˜å¯¹è±¡æ•°æ?®å­—段的值。reflection å?¯ä»¥ä»Žæ­£åœ¨è¿?行的程åº?中根æ?®å??称找到对象的字段并改å?˜å®ƒï¼Œä¸‹é?¢çš„例å­?å?¯ä»¥è¯´æ˜Žè¿™ä¸€ç‚¹ï¼š

import java.lang.reflect.*;

public class field2 {
   public double d;

   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“field2″);
           Field fld = cls.getField(“d”);
           field2 f2obj = new field2();
           System.out.println(“d = ” + f2obj.d);
           fld.setDouble(f2obj, 12.34);
           System.out.println(“d = ” + f2obj.d);
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

这个例�中,字段 d 的值被�为了 12.34。

9.使用数组

本文介�的 reflection 的最�一�用法是创建的�作数组。数组在 Java 语言中是一�特殊的类类型,一个数组的引用�以赋给 Object 引用。观察下�的例�看看数组是怎么工作的:

import java.lang.reflect.*;

public class array1 {
   public static void main(String args[]) {
       try {
           Class cls = Class.forName(“java.lang.String”);
           Object arr = Array.newInstance(cls, 10);
           Array.set(arr, 5, “this is a test”);
           String s = (String) Array.get(arr, 5);
           System.out.println(s);
       } catch (Throwable e) {
           System.err.println(e);
       }
   }
}

例中创建了 10 个��长度的 String 数组,为第 5 个�置的字符串赋了值,最�将这个字符串从数组中�得并打�了出�。

下é?¢è¿™æ®µä»£ç ?æ??供了一个更å¤?æ?‚的例å­?:

import java.lang.reflect.*;

public class array2 {
   public static void main(String args[]) {
       int dims[] = new int[]{5, 10, 15};
       Object arr = Array.newInstance(Integer.TYPE, dims);
       Object arrobj = Array.get(arr, 3);
       Class cls = arrobj.getClass().getComponentType();
       System.out.println(cls);
       arrobj = Array.get(arrobj, 5);
       Array.setInt(arrobj, 10, 37);
       int arrcast[][][] = (int[][][]) arr;
       System.out.println(arrcast[3][5][10]);
   }
}
例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。注�,多维数组实际上就是数组的数组,例如,第一个 Array.get 之�,arrobj 是一个 10 x 15 的数组。进而�得其中的一个元素,�长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。

注�创建数组时的类型是动�的,在编译时并�知�其类型。

technorati tags:

LOG4J的�置说明

Posted in 未分類·Uncategorized by yanwt on November 10, 2005

LOG4Jçš„é…?置之简å?•使它é??å?ŠäºŽè¶Šæ?¥è¶Šå¤šçš„应用中了:Log4Jé…?置文件实现了输出到控制å?°ã€?文件ã€?回滚文件ã€?å?‘é€?日志邮件ã€?输出到数æ?®åº“日志表ã€?自定义标签等全套功能。择其一二使用就够用了,

log4j.rootLogger=DEBUG,CONSOLE,A1,im
log4j.addivity.org.apache=true

# 应用于控制�

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n

#应用于文件

log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n
# Use this layout for LogFactor 5 analysis

# 应用于文件回滚

log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n

#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n

# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# ��日志给邮件

log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n

# 用于数�库
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES (‘[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n’)
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH’.log4j’
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender

log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net

log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d – %c -%-4r [%t] %-5p %c %x – %m%n

technorati tags:

在诺基亚中用NOKIA UI将图片å?˜æˆ?å?Šé€?明的程åº?

Posted in 未分類·Uncategorized by yanwt on November 3, 2005

/**
    * ��明渲染(�针对矩形区域)
    * @param g Graphics 图形对象
    * @param X int 渲染的矩形区域的å±?幕å??æ ‡X
    * @param Y int 渲染的矩形区域的å±?幕å??æ ‡Y
    * @param Width int 渲染的矩形区域的宽度
    * @param Height int 渲染的矩形区域的高度
    * @param Color int 渲染的颜色(�有�12�bit�有效)
    * @param transparence int  渲染程度,值越大,那么渲染色比例越大,背景色越�
    */
   protected void Game_Render_SemiTransparent(Graphics g, int X, int Y,
                                              int Width,
                                              int Height, int Color,
                                              int transparence) {
     int i;
     short pixels[] = new short[Width];
     for (i = 0; i        pixels[i] = (short) ( (transparence      }
     for (i = 0; i        DirectUtils.getDirectGraphics(g).drawPixels(pixels, true, 0,
           Width, X, i + Y, Width, 1, 0,
           DirectGraphics.
           TYPE_USHORT_4444_ARGB);
     }
     pixels = null;
   }

 

MIDlet的生命周期的深入�解�游�死机问题

Posted in 未分類·Uncategorized by yanwt on November 3, 2005

学习j2me,首先è¦?了解MIDlet的生命周期。本文主è¦?是深入了解一下MIDlet的生命周期。以上自己的个人心得,ä¸?对之处,希望大家多多指点。    首先在你è¿?行一个程åº?的时候,JAM会调用该midlet的构造函数æ?¥ç”Ÿæˆ?midlet的对象,然å?Žè¢«jam置于Paused状æ€?。一旦jam认为这个midlet对象å?¯ä»¥æ‰§è¡Œæ—¶ï¼Œjam就会调用startApp()方法,并将此midlet置于Active状æ€?。startApp()方法由于在系统æ?¥ç”µã€?或者退回到系统è?œå?•返回时会被å†?次调用,所以这里å?ªå?¯ä»¥æ”¾åˆ?始化一次的代ç ?。或者你把åˆ?始化一次的代ç ?放到midlet的构造函数中。例如:
public class Midlet extends MIDlet{
  Display display = null;
  MyCanvas can;
  public Midelt(){
      display = Display.getDisplay(this);
      can = new MyCanvas();
}
  public void startApp(){
     display.setCurrent(can);//如果把can = new MyCanvas()放到这里,å†?æ?¥ç”µè¿”回时就会出问题。
}
}
或者
public class Midlet extends MIDlet{
  Display display = null;
  MyCanvas can;
  public Midelt(){
}
  public void startApp(){
      if(display ==null){
       display = Display.getDisplay(this);
       can = new MyCanvas();
}//此处�会被�行1次,这样就�会出错
       display.setCurrent(can);//è¿™å?¥æŒ‰ç?†æ”¾åˆ°è¿™é‡Œæœ€å?ˆé€‚,你想显示那个canvas就放哪个ï¼?
}
}
在startApp()中,你调用display.setCurrent(can)的时候,首先�行的是showNotify(),接��行paint()函数一次,如果有线程的�,此时run()方法开始�行。一般在run()方法里一般这么写。此时的run()是�以处�异步事件的,也就是你�电�的时候,这里run()还是�行的。�过他�会paint()什么东西,�使它里�有repaint(),这点放心。

public void run(){
while(flag){//flag是boolean型��
try{
  Thread.sleep(50);//时间自己设啦。
}catch(Exception e){}
repaint();
}
}
哇~~�电�了,或者你退到系统��。如nokia s60的手机。
hideNotify()首先会被调用,接�pauseApp()�被调用。
这么快,打完了,返回时:先调用showNotify(),接�调用paint()函数一次,最��是调用startApp()函数。
关于run()和paint()也�以使用display.callSerially(this)语�。这个以�有时间了�说。
明白了生命周期,��看死机问题。我说的死机问题,多是�电�返回时死机。其实��找到了问题,一切就�的很简�。
为什么死机,归根结底还是程�问题。好�是废�。哈~~
Graphics mg;//定义的全局�数
paint(Graphics g){
mg = g;//有的程�这样写,if(mg ==null){mg =g:}这样对于n7610系列就会出错。
mg.drawString();
switch(case){
   case GAME_MUNE:
       drawA();
   break;
   case PLAY:
        drawB();
   break;
       default:
       break;
}
}

/*下�的画图函数一定�放到paint()函数里调用,��在别的地方调用,如run()里�,上�说过,程�暂�之�返回,会先paint()一次,如果在别的地方调用就会出现问题。*/
public void drawA(){
mg.drawString();
}
public void drawB(){
mg.drawString();
}
按照上�的写法一般�会出现死机问题。当然,你也�以�定义全局的mg,�以把g�独传到�个画图�函数中。如,
paint(Graphics g){
g.drawString();

switch(case){
   case GAME_MUNE:
       drawA(g);
   break;
   case PLAY:
        drawB(g);
   break;
      default:
       break;
}
}
public void drawA(Graphics mg){
mg.drawString();
}
public void drawB(Graphics mg){
mg.drawString();
}


Follow

Get every new post delivered to your Inbox.