参考:https://blog.csdn.net/yanshujun/article/details/6494447
package com.java.broadcast;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class EventCenter {
public static Map<EventType,Event> eventTable = new HashMap<>();
//添加某个对象要执行的事件,及需要的参数的类型
public static void addListener(EventType eventType,Object object,String methodName,Class... paramTypes){
if(!eventTable.containsKey(eventType)) eventTable.put(eventType,null);
Event temp = eventTable.get(eventType);
if(null!=temp&&temp.getParamTypes().length!=paramTypes.length)return;
boolean flag = true;
if (null!=temp)flag = equalsClassType(paramTypes,temp.getParamTypes());
if (!flag) return;
Event e = new Event(object,methodName);
e.setParamTypes(paramTypes);
e.setNextEvent(temp);
eventTable.put(eventType,e);
}
public static boolean equalsClassType(Class[] a , Class[] b){
boolean flag = true;
for (int i = 0; i < a.length; i++) {
if(a[i]!=b[i]){
flag = false;
break;
}
}
return flag;
}
public static void removeListener(EventType eventType,Object object,String methodName,Class... paramTypes){
if(!eventTable.containsKey(eventType)){
System.out.println("不存在要移除的监听事件类型");
return;
}
Event temp= new Event();
temp.setNextEvent(eventTable.get(eventType));
boolean flag = false;
int i=0;
while(temp.getNextEvent()!=null){
if(temp.getNextEvent().getObject()==object&&methodName.equals(temp.getNextEvent().getMethodName())){
flag = equalsClassType(paramTypes,temp.getNextEvent().getParamTypes());
if(flag)break;
}
i++;
temp = temp.getNextEvent();
}
if(flag){
if (i==0){//第一个元素就是要移除的元素
eventTable.put(eventType,temp.getNextEvent().getNextEvent());
}else {
Event next = temp.getNextEvent().getNextEvent();
temp.setNextEvent(next);
}
if (null==eventTable.get(eventType)){
eventTable.remove(eventType);
}
}
}
public static void Broadcast(EventType eventType,Object... params){
if(!eventTable.containsKey(eventType)){
System.out.println("广播的事件类型不存在");
return;
}
Event e = eventTable.get(eventType);
if(e==null)return;
Class[] paramTypes = contractParamTypes(params);//若是params没有参数则paramTypes==null
if (paramTypes==null&¶ms.length!=0)return;
boolean flag = true;
if(paramTypes!=null){
flag = equalsClassType(paramTypes,e.getParamTypes());
}
if(!flag)return;
eventTable.get(eventType).invoke(params);
}
//根据参数数组生成参数类型数组
private static Class[] contractParamTypes(Object[] params){
//此时会自动装箱,eg:如果params中有int 会自动装箱成Integer。
// 故外面的方法的参数最好是Integer之类的包装类型,而不是int之类的基本类型
if (params.length==0||params==null)return null;
Class[] paramTypes=new Class[params.length];
for(int i=0;i<params.length;i++){
paramTypes[i]=params[i].getClass();
}
return paramTypes;
}
//打印当前所有的监听事件
public static void ShowEventTable(){
Set<EventType> hashSet = eventTable.keySet();
for (EventType type:hashSet) {
Event e = eventTable.get(type);
System.out.println("object:"+e.getObject()+"method:"+e.getMethodName());
while(e.getNextEvent()!=null){
e = e.getNextEvent();
System.out.println("object:"+e.getObject()+"method:"+e.getMethodName());
}
}
}
}
package com.java.broadcast;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Event {
private Object object;//实体
private String methodName;//方法名字
private Class[] paramTypes;//参数的类型数组
private Event nextEvent = null;//下一个实体
public Class[] getParamTypes(){
return paramTypes;
}
public Object getObject() {
return object;
}
public String getMethodName() {
return methodName;
}
public void setParamTypes(Class[] paramTypes) {
this.paramTypes = paramTypes;
}
public Event getNextEvent() {
return nextEvent;
}
public void setNextEvent(Event nextEvent) {
this.nextEvent = nextEvent;
}
public Event(Object object, String methodName){
this.object=object;
this.methodName=methodName;
}
public Event(){}
//执行该 对象的该方法
public void invoke(Object... params){
Method method= null;
try {
method = object.getClass().getMethod(this.getMethodName(), this.getParamTypes());
if(null==method)return;
method.invoke(this.getObject(), params);
if(this.nextEvent!=null)nextEvent.invoke(params);
else return;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
package com.java.broadcast;
public enum EventType {
// Show,
// FaZhan,
//Write,
}
test:
package com.java.broadcast;
public class TestMain {
public static void main(String[] args){
Student s = new Student();
EventCenter.addListener(EventType.Show,s,"show",String.class);
EventCenter.addListener(EventType.FaZhan,s,"fazhan",String.class,Integer.class);
EventCenter.addListener(EventType.Show,s,"read",String.class);
EventCenter.addListener(EventType.Write,s,"write");
EventCenter.Broadcast(EventType.Write);
Teacher t = new Teacher();
t.buzhi();
t.chengfa("上课泡妞",60);
EventCenter.ShowEventTable();
}
}
package com.java.broadcast;
public class Student {
public void show(String str){
System.out.println("老师布置作业了,我正在写老师布置的作业:"+str);
}
public void read(String str){
System.out.println("这是read()方法:"+str);
}
public void write(){
System.out.println("这是write()方法:");
}
public void fazhan(String str,Integer time){
System.out.println("我正在罚站,原因:"+str+"时间:"+time+"min");
}
}
package com.java.broadcast;
public class Teacher {
public void buzhi(){
System.out.println("我要布置作业了");
EventCenter.Broadcast(EventType.Show,"数学试卷抄一百遍");
}
public void chengfa(String str,int time){
System.out.println("我要惩罚你");
EventCenter.Broadcast(EventType.FaZhan,str,time);
}
}