我们平常在开发web项目的时候,经常会使用SSH来构建我们的项目,也有很多程序猿喜欢用注解来减少代码量。但是各位屌丝程序猿们,大家有没有想过这个注解是怎么实现的呢。我们又该如何写出像注解这么优雅的代码呢。除了我们平时在写代码的时候看到了新的东西之后始终保持探索的精神。还要有大家拿出极大的热情刻苦专研和对待代码一丝不苟的精神。这样才能使得自己进步,写出更加优雅的代码。今天我带大家来写一个注解类,初始化android控件。
废话少说,先上一段代码。
package com.example.volley.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//声明在field
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
int value() default 0;
}
首先看这段代码,相信大家之前没有写过的童鞋肯定看的一头雾水。所以我解释一些。@interface这是java用来定义一个注解类。
@Target和@Retention这两个是JDK提供的元注解。请看下面。
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
简单解释一下,比如ElementType.TYPE这个表示是一个类注解。比如struts2和springMVC的@controller
这个注解。
RetentionPolicy.RUNTIME表示会在class文件中运行是通过反射得到。
注解类写好了,下面关键的是如何注解解析。
老办法,先上代码。
package com.example.volley.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.Activity;
public class ViewUtils {
public static ViewUtils viewUtils;
public Activity ctx;
public ViewUtils(Activity ctx) {
this.ctx = ctx;
autoInjectAllField();
}
public static ViewUtils inject(Activity ctx){
if (viewUtils!=null) {
return viewUtils;
}else{
viewUtils = new ViewUtils(ctx);
return viewUtils;
}
}
private void autoInjectAllField() {
try {
Class<?> clazz = ctx.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ViewInject.class)) {
ViewInject inject = field.getAnnotation(ViewInject.class);
int id = inject.value();
if(id > 0){
field.setAccessible(true);
field.set(ctx, ctx.findViewById(id));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过ctx.getclass()得到实体类。然后得到这个类中所有的注解跟ViewInject注解类匹配。如果匹配成功,则set(ctx,ctx.findById());