java监听机制的原理-回调机制
2016-07-28 12:18
471 查看
在java
me中,可以对一个Button添加一个鼠标点击事件,可以对一个文本框添加一个文本变化事件等等;在Android开发中,也有大量这种基于事件的处理。
探究其基本原理,则是对方法的回调。具体的看下面简单的代码即可了解
首先创建一个接口:TextListener,接口内有一个名叫exchute()的方法
public interface TextListener {
public void excute();
}
可以看到,接口中并没有excute()方法的具体实现。
接下来创建一个类:Text,这个类中包含了几个东西:第一个,TextListener的集合,因为可以为Text添加多个TextListener监听,因此,用一个集合来保存所有的监听;第二个addTextListener(TextListener
tl),这个方法是给Text注册监听的,说的通俗一点,就是把一个新的监听添加到TextListener集合中去;第三个方法removeListener(TextListener
tl),顾名思义,就是把某个监听从监听集合中移除,第三个方法叫excute(),这里不要和TextListener中的excute()方法混淆了,这个方法的作用就是回调注册了的TextListener,执行其中的代码。
import java.util.List;
import java.util.Vector;
public class Text {
private List listeners = new Vector<>();
public Text() {
}
public void addTextListener(TextListener listener) {
listeners.add(listener);
}
public void removeTextListener(TextListener listener) {
listeners.remove(listener);
}
public void excute() {
for (TextListener t : listeners) {
t.excute();
}
}
}
注:Text中的excute()方法,实际上就是遍历监听集合中的所有元素,依次调用TextListener的excute()方法。额。。。希望没有把这两个excute方法混淆了,命名可以随便改。
然后,写一个main函数,来运行着写代码:
public static void main(String[] args) {
Text text = new Text();
text.addTextListener(new TextListener() {
@Override
public void excute() {
System.out.println("cc is better man");
}
});
text.addTextListener(new TextListener() {
@Override
public void excute() {
int size = 100;
int rst = 0;
for (int i = 0; i < size; i++) {
rst += i;
}
System.out.println("the sum of 0 to 100 is :" + rst);
}
});
text.excute();
}
说明:首先创建了一个Text对象,再为Text对象添加了两个TextListener的监听,每个监听里面实现的excute()方法不一样,最后,再调用text.excute()方法,就会依次执行注册了的监听。在这个地方,由于text中,监听集合实际上是一个接口的集合,Text并不知道调用接口的excute()方法后,会执行什么代码,在注册的时候,接口的excute()方法的实现,也不会执行,所以,为text添加监听的时候,text也不知道自己在执行excute()方法的时候,输出结果是什么。
对于这种基于注册机制,来调用接口方法的用法,就是回调机制。
按道理来讲,在添加监听的时候,是实现了一个接口的,也就是说,在这个时候,创建了一个接口的实例,并且将这个实例放在内存中了,text的addTextListener方法,实际上存了一个这个接口实例的一个引用地址。当执行text.excute()方法的时候,会根据注册的TextListener的内存地址,来找到这个监听接口的实例,然后再调用TextListener的excute方法。
其实,上述代码还有一种写法,那就是创建一个类,实现TextListener接口的excute()方法,然后,new一个这个类,把这个类注册到text的监听里面,也能够实现同样的效果。
代码如下:
public class TextListenerImpl
implements TextListener {
@Override
public void excute() {
System.out.println("回调了这个方法~~~~~");
}
}
text.addTextListener(new
TextListenerImpl());//此为注册方法
其实这样子看的话,会比较清晰,当然,这个TextListener的实现类中的excute方法具体要执行什么,text依然不知道。
不知道这样子有没有说清楚。先这样吧。
me中,可以对一个Button添加一个鼠标点击事件,可以对一个文本框添加一个文本变化事件等等;在Android开发中,也有大量这种基于事件的处理。
探究其基本原理,则是对方法的回调。具体的看下面简单的代码即可了解
首先创建一个接口:TextListener,接口内有一个名叫exchute()的方法
public interface TextListener {
public void excute();
}
可以看到,接口中并没有excute()方法的具体实现。
接下来创建一个类:Text,这个类中包含了几个东西:第一个,TextListener的集合,因为可以为Text添加多个TextListener监听,因此,用一个集合来保存所有的监听;第二个addTextListener(TextListener
tl),这个方法是给Text注册监听的,说的通俗一点,就是把一个新的监听添加到TextListener集合中去;第三个方法removeListener(TextListener
tl),顾名思义,就是把某个监听从监听集合中移除,第三个方法叫excute(),这里不要和TextListener中的excute()方法混淆了,这个方法的作用就是回调注册了的TextListener,执行其中的代码。
import java.util.List;
import java.util.Vector;
public class Text {
private List listeners = new Vector<>();
public Text() {
}
public void addTextListener(TextListener listener) {
listeners.add(listener);
}
public void removeTextListener(TextListener listener) {
listeners.remove(listener);
}
public void excute() {
for (TextListener t : listeners) {
t.excute();
}
}
}
注:Text中的excute()方法,实际上就是遍历监听集合中的所有元素,依次调用TextListener的excute()方法。额。。。希望没有把这两个excute方法混淆了,命名可以随便改。
然后,写一个main函数,来运行着写代码:
public static void main(String[] args) {
Text text = new Text();
text.addTextListener(new TextListener() {
@Override
public void excute() {
System.out.println("cc is better man");
}
});
text.addTextListener(new TextListener() {
@Override
public void excute() {
int size = 100;
int rst = 0;
for (int i = 0; i < size; i++) {
rst += i;
}
System.out.println("the sum of 0 to 100 is :" + rst);
}
});
text.excute();
}
说明:首先创建了一个Text对象,再为Text对象添加了两个TextListener的监听,每个监听里面实现的excute()方法不一样,最后,再调用text.excute()方法,就会依次执行注册了的监听。在这个地方,由于text中,监听集合实际上是一个接口的集合,Text并不知道调用接口的excute()方法后,会执行什么代码,在注册的时候,接口的excute()方法的实现,也不会执行,所以,为text添加监听的时候,text也不知道自己在执行excute()方法的时候,输出结果是什么。
对于这种基于注册机制,来调用接口方法的用法,就是回调机制。
按道理来讲,在添加监听的时候,是实现了一个接口的,也就是说,在这个时候,创建了一个接口的实例,并且将这个实例放在内存中了,text的addTextListener方法,实际上存了一个这个接口实例的一个引用地址。当执行text.excute()方法的时候,会根据注册的TextListener的内存地址,来找到这个监听接口的实例,然后再调用TextListener的excute方法。
其实,上述代码还有一种写法,那就是创建一个类,实现TextListener接口的excute()方法,然后,new一个这个类,把这个类注册到text的监听里面,也能够实现同样的效果。
代码如下:
public class TextListenerImpl
implements TextListener {
@Override
public void excute() {
System.out.println("回调了这个方法~~~~~");
}
}
text.addTextListener(new
TextListenerImpl());//此为注册方法
其实这样子看的话,会比较清晰,当然,这个TextListener的实现类中的excute方法具体要执行什么,text依然不知道。
不知道这样子有没有说清楚。先这样吧。
相关文章推荐
- SpringBoot+Shiro+SpringSession的简单集成配置简要步骤
- JAVA/SERVLET 以UTF-8导出CSV文件时产生乱码的解决方法
- Java中比较器小结
- 整合DataTables到JavaWeb(SSH)实例总结分析
- 影响Java线程数、Server连接数的几个系统参数
- java读取classpath下的properties文件
- (12)SSH整合中的web.xml文件
- java系统高并发解决方案(转载)
- java 冒泡排序
- java实现FTP下载文件
- Myeclipse快捷键
- java对象的强引用,软引用,弱引用和虚引用
- 使用 Spring 的 AOP 机制来输出 Log
- 70.打印所有Spring boot载入的bean【从零开始学Spring Boot】
- 线性表(java)
- java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
- JAVAWEB引语
- JAVA设计模式
- struts.xml配置文件元素的说明
- java(优化15) 报错"java.lang.ClassNotFoundException: net.sf.ezmorph.Morpher"解决方案