Java如何实现事件驱动机制的实例
这篇文章主要介绍了浅谈用java实现事件驱动机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
由于项目需求,需要为Java提供一套支持事件驱动机制的类库,可以实现类似于C#中的event和delegate机制。众所周知,Java语言本身以及其标准库中并没有提供事件驱动机制的相关接口,虽然Swing(我且认为其不属于标准库,因为一般没人用:)中存在相关的类支持该机制以实现组件的事件处理,但它毕竟是与GUI相耦合的,而在其它类型的应用程序中使用起来显得就有些别扭,缺乏通用性。因此有必要实现一套通用的Java事件驱动机制类库,然后将其应用于通用的Java应用程序当中,虽然这并不是什么难事:)
让我们先考察一下C#的事件驱动机制编写方法。C#中提供的event关键字可以很容易的用来定义一个事件,然后通过向事件中添加事件处理函数(在C#中一般用委托(delegate)来引用一个函数),触发事件就可以调用相关的处理函数,也即是事件驱动的过程。例如:
//定义事件和对应的委托 public event MyDelegate Click; public delegate void MyDelegate(); //定义委托 void OnClick(){ console.writeline("you just clicked me!"); } //将委托与事件关联 Click += OnClick; //触发事件 Click();
上面的代码就是用C#实现的事件驱动机制的一个简单的例子,可见是非常简单的,这都源于C#在语言层面(其实是CLR)提供的便利。遗憾的是Java并不提供这样的便利,需要人为去实现。下面本文将提供两种实现事件驱动机制的方法,仅供参考。
观察者模式
观察者模式是一种常用的设计模式,观察者(Observer)先通过订阅被观察对象(Subject),这样一旦被观察者(Subject)发生某种变化,就会将变化通知观察者(Observer)。
这种设计模式刚好可以用于事件驱动机制,事件(event)相当于被观察对象(Subject),一旦事件被触发,就会调用事件处理函数,可见事件处理函数(C#中的委托)可以看作是观察者。因此可以像如下这样实现上文中的功能。
/*事件类*/ public Event { //与事件相关的事件处理函数 public ArrayList<Callback> callbackList; //事件触发函数 public void emit(){ for(Callback cb : callbackList){ cb.run(); } } //注册事件处理函数 public registerCallback(Callback cb){ callbackList.add(cb); } } /*事件处理函数类*/ public interface Callback { void run(); } public OnClick implements Callback { //函数 public void run(){ System.out.println("you just clicked me!"); } /*实现事件驱动*/ Event e = new Event(); //将OnClick事件处理函数注册到事件中 e.registerCallback(new OnClick()); //触发事件 e.emit();
上面的Java代码实现了一种简单的事件驱动机制,原理很简单,是一种典型的观察者模式的应用案例。
利用反射
Java语言提供强大的反射功能,可以在运行时获取类的各个组成部分(比如类名、类成员函数、类属性等等)并对其进行操作。下面使用反射来实现简单的事件驱动机制。
/*事件处理类*/ public class EventHandler { //事件源 private Object sender; //事件处理函数名称(用于反射) private String callback; public EventHandler(Object sender, String callback){ this.sender = sender; this.callback = callback; } //事件触发 public void emit(){ Class senderType = this.sender.getClass(); try { //获取并调用事件源sender的事件处理函数 Method method = senderType.getMethod(this.callback); method.invoke(this.sender); } catch (Exception e2) { e2.printStackTrace(); } } } /*事件源*/ public class Button(){ /*可以在此设置Button类的相关属性,比如名字等*/ private String name; ... //事件处理函数 public void onClick(){ System.out.println("you just clicked me!"); } } /*实现事件驱动机制*/ Button b = new Button(); if(/*收到按钮点击信号*/){ EventHandler e = new EventHandler(b, "onClick"); e.emit(); }
上述代码展示了利用反射实现的事件驱动机制,利用反射机制的好处是其具有强大的扩展性,比如我的事件处理函数中可以引入一个EventArgs的形参,从而可以让事件本身带有参数,这样就可以让事件携带更多的信息,改写后的事件处理函数如下方的代码所示:
public class EventArgs { //参数 String p1; Integer p2; ... } //onClick事件处理函数改写 public void onClick(Object sender, EventArgs e){ //参数e提供更多的信息 System.out.println("Hello, you clicked me! " + e.p1 + e.p2); } //触发函数emit改写 public void emit(EventArgs e){ Class senderType = this.sender.getClass(); try { //获取并调用事件源sender的事件处理函数 Method method = senderType.getMethod(this.callback, this.getClass(), e.getClass()); method.invoke(this.sender, this.sender, e); } catch (Exception e2) { e2.printStackTrace(); } }
是不是似曾相识?没错,和用C#写Winform窗体时,Visual studio为你自动生成的事件处理函数(代码中的onClick函数)几乎具有完全相同的形式,但此时我们是用Java实现的。
当然,除了以上提到的两种方法可以实现Java的事件驱动机制以外,还有一些其它的方法,比如可以利用Java的内部类来实现,笔者也曾写过一些示例代码,这里就不再冗言了,留待以后再讲。
Atas ialah kandungan terperinci Java如何实现事件驱动机制的实例. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Square Root di Java. Di sini kita membincangkan cara Square Root berfungsi di Java dengan contoh dan pelaksanaan kodnya masing-masing.

Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Penjana Nombor Rawak di Jawa. Di sini kita membincangkan Fungsi dalam Java dengan contoh dan dua Penjana berbeza dengan contoh lain.

Panduan untuk Nombor Armstrong di Jawa. Di sini kita membincangkan pengenalan kepada nombor Armstrong di java bersama-sama dengan beberapa kod.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah
