什么是注解
@Override重写 @Deprecated 已过期 这些都是我们常见的注解。
-
从作用角度讲 注解是干嘛的呢?
注解是起到解释说明作用的。 比如@Override说明这个方法是重写的父类的方法,如果父类没有这个方法编辑器就会贴心的给你红线警告了
-
本质上讲注解是什么呢
如何定义注解
源注解
定义一个注解就要先了解“元注解”,元注解就是修饰注解的注解主要是有以下四种
-
@Target,修饰注解的范围也就是说我们定义的这个注解可以用在什么地方
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
-
@Retention,描述的是注解能修饰的生命周期,源码阶段,编译的class阶段和加载到JVM的RunTime阶段
-
@Documented, doc文档
-
@Inherited 用这个修饰的注解被用于类的时候 这个类的子类也被这个注解修饰
注解元素
注解元素就是注解主体里的一些抽象方法。抽象方法的特点是没有方法但是有返回值和方法名,而且注解里面的抽象方法没有方法参数。如下
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Student { int value(); String name() default "";}复制代码
特殊的当注解中只有一个方法并且方法名为value时可以不用写可以直接写value
如何使用
注解种的值可以使用反射获取到然后做相应的处理。
- 创建注解
/** * Created by WESHAPE-DEV02 on 2017/12/21. */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface StudentDes { String name() default ""; int ID() default -1;}复制代码
特殊的当注解中只有一个抽象方法且方法名为value的时候z在使用注解添加属性值的时候可以不用标注使用(value = xxx)而是直接(XXX)
- 使用注解
@StudentDes(ID = 1008,name = "Frank")public class Student { String name ; int ID ; static void getStudent(Student student){ Class cls = student.getClass(); StudentDes studentDes = (StudentDes) cls.getAnnotation(StudentDes.class); /** * 在注解中获取名字和学号 */ String name = studentDes.name(); int ID = studentDes.ID(); Field[] fields = cls.getFields(); for(Field field:fields){ if(field.getName().equals("name")) { try { field.setAccessible(true); field.set(student,name);//设置名字 } catch (IllegalAccessException e) { e.printStackTrace(); } }else if (field.getName().equals("ID")){ try { field.setAccessible(true); field.set(student,ID);//设置学号 } catch (IllegalAccessException e) { e.printStackTrace(); } } } }}复制代码
注解的运用
模拟一个butterknife的功能
- 定义一个修饰Activity中View这种属性的注解如下:
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface BindView { int value(); String getMyName() default "";}复制代码
- 写一个工具类
public class BindViewUtil { public static void binderView(Activity activity){ Class mcls = activity.getClass(); Field[] fields = mcls.getFields(); for(Field field:fields){ BindView bindView = field.getAnnotation(BindView.class); if(bindView!=null) { int viewID = bindView.value(); bindView.getMyName(); View view = activity.findViewById(viewID); try { field.setAccessible(true); field.set(activity,view); } catch (IllegalAccessException e) { e.printStackTrace(); } } } }}复制代码
- 使用
public class MainActivity extends Activity { @BindView(R.id.view_a) TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); BindViewUtil.binderView(this); }}复制代码
时间仓促,不免鄙陋,望诸君不吝指正。