【JAVA】Java事件模型

Java事件模型 .
分类: Java 2007-07-28 14:01 924人阅读 评论(1) 收藏 举报 
 在我的前两篇介绍C#事件和委托的blog 发表之后,大家响应特别热烈,点击率很高,看来事件/委托机制是很多同仁比较模糊的地方,借此东风,加上最近自己转战java,于是决定写这篇介绍java事件机制的blog。 
     其实,不管哪种语言的事件机制,毫无例外都逃不出三点:事件源/发送者,事件的接受者/处理者/侦听者,以及事件源向事件接受者传递的事件信息。对应在java中,事件源 (event source),事件倾听者 (event listener),事件消息称为eventobject。而在C#中,分别是发送者(Sender),处理者(handler),事件消息则是事件参数(EventArgument)。而java和c#都采用相同的响应模式:发布者/订阅者模式(publisher/subscriber),具体来说就是:

    (1)订阅者向发布者注册自己感兴趣的事件;

    (2)事件发生时,通知订阅者响应事件。

    简单一句话,就是那句常说的:“Don't call me,I'll call you。”

    由于之前已经对C#的事件机制进行了探讨,下面,我将着重谈谈java的事件机制,以及对两者实现机制的比较:

    (一)Java事件实现机制

下面是一个自定义java事件的例子,通过这个简单的演示,你可以看到Java的事件实现机制。这里说明一下,这个例子引自http://www.rainsts.net/article.asp?id=224,为了说明原理,改编了原文中对匿名方法部分。 

import java.util.*;

// 定义一个类似 C# EventArgs 的类用来传递事件状态信息。
// 一般要求继承自 java.util.EventObject,且以 Event 结尾。
Class ClicktEventclass ClicktEvent extends EventObject{
   public DemoBean source;
     //构造函数的参数传递产生事件的事件源
   public ClickEvent(DemoBean source)    {
     super(source);
     this.source = source;
   }
}

// 通过接口来定义事件响应函数原型,就像c# delegate定义了响应函数的“模板”,// 别忘了,接口实际上就是一种“合同”,“契约”,通过这个接口中的函数签名达到对响应函数的规范
// 一般要求继承自 java.util.EventListener,且以 Listener 结尾。//这里以I开头定义ClickListener接口,借鉴自.net,不符合j2ee的命名规范
Interface IClickListenerinterface IClickListener extends EventListener { 
    void click(ClicktEvent e);
 }  //事件侦听者,实现侦听者接口 public Class ClickListenerclass ClickListener implements IClickListener  {     public  void click(ClicktEvent e)     {        System.out.println( "the clicked event happened");     }
  } 

// 定义演示控件类,也就是事件源
Class DemoBeanclass DemoBean {
  
  // 用一个java.util.Vector对象来存储所有的事件监听器对象。  private Vector clicks = new Vector();
  
  // 添加事件订阅。一般以 add( listener)方式拼写,并添加 synchronized 关键字。
  public synchronized void addExampleListener(IClickListener listener)  {
    clicks.add(listener);
  }

  // 移除事件订阅。一般以 remove( listener)方式拼写,并添加 synchronized 关键字。
  public synchronized void removeExampleListener(IClickListener listener)  {
    clicks.remove(listener);
  }
  
  // 触发事件。
  protected void doClickEvent()   {

    // 锁定,避免在触发期间有事件被订阅或移除。
    synchronized (this)      {

      // 创建事件状态对象。
      ClicktEvent ce = new ClickEvent(this);
      
      // 循环触发所有的事件订阅方法。
      for (int i = 0; i < clicks.size(); i++)       {
          IClickListener e = (IClickListener)clicks.get(i);
          e.click(ce);
       }
     }
  }
  
  // 模拟点击操作。
  public void Click()  {
    doClickEvent();
  }
}
//测试程序
public Class Programclass Program{

  public static void main(String[] args)   {

    // 创建控件。
    DemoBean bean = new DemoBean();    //实例化一个事件侦听者   ClickListner testListner=new ClickListner(); 
       // 添加事件订阅。
    bean.addExampleListener (testListner);
    
    // 模拟触发点击操作。
    bean.Click();
  }
}
输出结果:the clicked event happened 
(二)事件实现机制的比较(Java/C#)

     总体来说,c#沿袭了C/C++中的函数回调机制,通过委托对函数指针的封装来实现对响应函数的调用;而java则通过接口来规范响应函数,使用多态的方式在运行时实现对事件接收者的响应函数的调用,应该说,这才是一种面向对象的机制。当然,两种方式各有千秋,下表是对两者的比较:

  java c# 说明 
效率 采用多态,相对高 采用委托,相对低。 应该说,它们都是在运行时获取对哪个对象的哪个方法进行调用,但是采用多态相对于委托效率高一点。 
是否支持静态方法调用 否 是
 java采用多态,当然不能把方法声明为static;c#中delegate中的_object可以为null来实现对静态方法的调用 
是否类型安全 是 是 它们都会在编译时对响应函数进行参数检查,类型安全。 
开发者易用性 两级实体对象:事件源-与事件响应者 三级实体对象:事件源-委托-事件响应者 由于有delegate的封装,不用编写事件注册/注销之类的代码,c#事件处理易用性相对高;注意,虽然java中采用接口来规范响应函数,但这里却说java中是两级实体对象,是因为在运行时并不存在接口的实例(实际上,接口也不可实例化,呵呵)  
  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值