java注解的使用方法
注解在用的时候其实也用到了反射,学习源自于工作,需求如下:机器人有各种监听,比如头部监听,翅膀监听等等各种监听,当机器人处于学习英语状态的时候,拍头事件发生,这个时候就需要中断,基于这个封装了一个类似android系统的touch事件分发的框架来处理事件,其中用到注解的是,学英语类中有一个方法加了@head_key注解的话代表着学英语状态关注头部事件,这时候就给它分发头部事件。
- 注解的写法
解释下:上面代码块的意思是定义了一个名字叫SubscribeRobotEvent的注解,注解作用于方法上面,被JVM保留,能在运行时被jvm虚拟机反射或者其他反射代码所反射。@Target和@Retention是java自带的,自己可以去查解释,同时这个注解可以接收一个InputEventType类型的数组,这里写的数组名字叫value这样在用的时候不用指清楚是哪个接收,如果这里数组名叫tags,那么接收的时候必须用tags,自己可以尝试一下。
使用如下
处理的代码如下,达到的目的是方法上面有InputEventType.HEAD_KEY时就执行此方法,模仿的eventbus,但是没得人家高效,工具类如下,注意dispatchRobotEvent方法
package com.efrobot.speech.utils;
import android.util.Log;
import com.efrobot.speech.OnRobotEventDispatchListener;
import com.efrobot.speech.input.InputEvent;
import com.efrobot.speech.model.SubscribeModel;
import com.efrobot.speech.subscribe.SubscribeRobotEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by zhangyun on 2017/3/8.
*/
public class EventBus implements OnRobotEventDispatchListener{
private static final String TAG = "EventBus";
private static final Map<Class<?>, List<SubscribeModel>> METHOD_CACHE = new ConcurrentHashMap<Class<?>, List<SubscribeModel>>();
static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
public void register(Object subscriber) {
Log.e(TAG, "register: " );
Class<?> subscriberClass = subscriber.getClass();
List<SubscribeModel> subscriberMethods = METHOD_CACHE.get(subscriberClass);
synchronized (this) {
if (subscriberMethods != null) {
METHOD_CACHE.remove(subscriberClass);
}
List<SubscribeModel> subscriberMethods1 = new ArrayList<SubscribeModel>();
for (Method it : subscriberClass.getMethods()) {
if (it.isAnnotationPresent(SubscribeRobotEvent.class)) {
SubscribeRobotEvent receive = it.getAnnotation(SubscribeRobotEvent.class);
SubscribeModel annotationBean = new SubscribeModel();
annotationBean.setObject(subscriber);
annotationBean.setMethod(it);
annotationBean.setType(new HashSet(Arrays.asList(receive.value())));
subscriberMethods1.add(annotationBean);
}
}
METHOD_CACHE.put(subscriberClass, subscriberMethods1);
}
}
@Override
public Object dispatchRobotEvent(InputEvent event) {
boolean result = false;
try {
for (Map.Entry<Class<?>, List<SubscribeModel>> entry : METHOD_CACHE.entrySet()) {
List<SubscribeModel> annotationBeanList = entry.getValue();
for (SubscribeModel it : annotationBeanList) {
Log.e("tag" , "EventBus :: it.getType().contains(event.getType() :: " + it.getType().contains(event.getType()));
if (it.getType().contains(event.getType())) {
result = (Boolean) it.getMethod().invoke(it.getObject(), event);
}
}
}
} catch (InvocationTargetException e) {
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
Log.e("tag" , "EventBus :: result :: " + result);
return result;
}
public static synchronized void unregister(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
if (METHOD_CACHE.get(subscriberClass) != null) {
METHOD_CACHE.remove(subscriberClass);
}
}
}
- 百度搜索“onclick 注解”一大堆关于如何@一下id就可以收到onclick事件的,核心的在于通过反射拿到带有注解的id的值然后findbyid一下然后在设置一下onclicklistener就可以了,相当于自己写回调吧,这里不演示,戳这里http://blog.csdn.net/z23546498/article/details/52843846
注解及扩展
以下的基础知识全都抄自于java编程思想。 —— [ java编程思想 ]
注解能达到的目的:
1、可以用来生成描述性文件甚至或是新的类定义。
2、有助于减轻编写“样板”代码的负担
3、更加干净易读的代码以及编译期类型检查等。
java内置三种注解
1、Override 表示当前的方法定义将覆盖超类中的方法。
2、Deprecated 表示如果程序猿使用了注解为它的元素,那么编译器会发出警告信息。
3、SuppressWarnings ,关闭不当的编译警告信息。
定义注解
定义一个注解的时候需要用到元注解@Target 表示用在方法上还是属性上还是类上面@Retention表示注解在哪一个级别上可用,具体看源码翻译。
没有元素的注解称为标记注解
注解处理器
它就是通过反射得到实例的方法然后得到这个方法上所对应的注解就可以获得注解里面变量的值。反射相关的内容戳这里:
注解元素
我所理解的注解的元素就是指的注解里面所定义的变量,注解和接口不同的地方在于注解可以给变量附一个默认值,注解所支持的变量类型如下: