自定义注解(Annotation)基本使用
2018-01-28 21:33
741 查看
从 jdk5开始,Java增加了对元数据的支持,也就是Annotation,Annotation其实就是对代码的一种特殊标记,这些标记可以在编译,类加载和运行时被读取,并执行相应的处理。当然刚刚说了,Annotation只是一种标记,所以要是在代码里面不用这些标记也是能完成相应的工作的,只是有时候用注解能简化很多代码,看起来非常的简洁。
自定义注解MyAnnotation2
在实例中使用
测试
打印结果
MainActivity
绑定控件
绑定布局
绑定点击事件
工具类(通过反射操作相关逻辑)
基本的Annotation
● @Override——限定重写父类方法 ● @Deprecated——标示已过时 ● @SuppressWarning——抑制编译器警告 ● @SafeVarargs——这货与Java7里面的堆污染有关
JDK的元Annotation,元注解
JDK除了提供上述的几种基本的Annotation外,还提供了几种Annotation,用于修饰其他的Annotation定义 1. @Retention 这个是决定你Annotation存活的时间的,它包含一个RetationPolicy的value成员变量,用于指定它所修饰的Annotation保留时间,一般有: ○ Retationpolicy.CLASS:编译器将把Annotation记录在Class文件中,不过当java程序执行的时候,JVM将抛弃它。 ○ Retationpolicy.SOURCE : Annotation只保留在原代码中,当编译器编译的时候就会抛弃它。 ○ Retationpolicy.RUNTIME : 在Retationpolicy.CLASS的基础上,JVM执行的时候也不会抛弃它,所以我们一般在程序中可以通过反射来获得这个注解,然后进行处理。 2. @Target 这个注解一般用来指定被修饰的Annotation修饰哪些元素,这个注解也包含一个value变量: ○ ElementType.ANNOTATION_TYPE : 指定该Annotation只能修饰Annotation。 ○ ElementType.CONSTRUCTOR: 指定只能修饰构造器。 ○ ElementType.FIELD: 指定只能成员变量。 ○ ElementType.LOCAL_VARIABLE: 指定只能修饰局部变量。 ○ ElementType.METHOD: 指定只能修饰方法。 ○ ElementType.PACKAGE: 指定只能修饰包定义。 ○ ElementType.PARAMETER: 指定只能修饰参数。 ○ ElementType.TYPE: 指定可以修饰类,接口,枚举定义。 3. @Document 这个注解修饰的Annotation类可以被javadoc工具提取成文档 4. @Inherited 被他修饰的Annotation具有继承性
例子
自定义注解MyAnnotation@Retention(RetentionPolicy.RUNTIME)//运行时 @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//范围类接口,方法,变量 //@Deprecated //标记过时 @Inherited //注解可被继承 public @interface MyAnnotation { String value();//只有一个方法是用value() }
自定义注解MyAnnotation2
@Retention(RetentionPolicy.RUNTIME)//运行时 @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//范围类接口,方法,变量 //@Deprecated //标记过时 @Inherited //注解可被继承 public @interface MyAnnotation2 { String name2(); int age2(); }
在实例中使用
@MyAnnotation("类注解") public class User { @Deprecated private String userName; @Deprecated public void fun() { //已过时 } @MyAnnotation("fun2方法注解") public void fun2(){ } @MyAnnotation2(name2 = "Coco",age2 = 22) public void fun3(){ } }
测试
public static void main(String[] args) { try { //得到user字节码 Class c = Class.forName("com.bwie.reflectdemo1.User"); //通过反射得到fun3 Method method = c.getMethod("fun3", null); //得到fun3上的注解 MyAnnotation2 myAnnotation2 = method.getAnnotation(MyAnnotation2.class); //打印结果 System.out.println(myAnnotation2.name2()+"--fun3上的注解(多值)--"+myAnnotation2); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } }
打印结果
Coco--fun3上的注解(多值)--@com.bwie.reflectdemo1.annotation.MyAnnotation2(name2=Coco, age2=22)
例子2
* 绑定控件,绑定布局,绑定点击事件*MainActivity
/** * 1.自定义类注解和成员变量注解 * 2.绑定主布局 * 3。绑定控件 */ @ContentView(R.layout.activity_main) public class MainActivity extends AppCompatActivity { @BindView(R.id.tv) TextView textView; /*@BindView(R.id.btn) Button button;*/ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); InjectUtils.inject(this); System.out.println(textView); textView.setText("++++++++++++++++"); } @MClick({R.id.btn}) public void click(View view) { Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show(); } }
绑定控件
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Documented @Inherited public @interface BindView { int value(); }
绑定布局
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Inherited public @interface ContentView { int value(); }
绑定点击事件
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MClick { int[] value(); }
工具类(通过反射操作相关逻辑)
public class InjectUtils { /** * 注入activity,通过反射运行相关逻辑 */ public static void inject(Activity activity) { injectContentView(activity); injectBindView(activity); injectBindOnClick(activity); } //绑定点击事件 private static void injectBindOnClick(final Activity activity) { Class c = activity.getClass(); Method[] methods = c.getDeclaredMethods(); for (final Method method : methods) { method.setAccessible(true); MClick annotation = method.getAnnotation(MClick.class); if (annotation != null) { int[] value = annotation.value(); for (int i : value) { int id = i; final View btn = activity.findViewById(id); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { method.invoke(activity,btn); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } Log.d(TAG, "onClick: "+1); } }); } } } } //注入contentview private static void injectBindView(Activity activity) { //得到activity字节码 Class clazz = activity.getClass(); Field[] fields = clazz.getDeclaredFields(); if (fields != null && fields.length > 0) { for (Field field : fields) { //设置权限 field.setAccessible(true); //得到成员变量的注解 BindView bindView = field.getAnnotation(BindView.class); if (bindView != null) { //注释的值 int value = bindView.value(); //得到每个id的view View view = activity.findViewById(value); try { field.set(activity,view); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } } /** * 绑定contentview,实现其逻辑 */ private static void injectContentView(Activity activity) { //得到Activity字节码 Class clazz = activity.getClass(); //得到类上面的注解 ContentView contentView = (ContentView) clazz.getAnnotation(ContentView.class); if (contentView!=null){ int layoutId = contentView.value(); try { Method method = clazz.getMethod("setContentView", int.class); method.invoke(activity,layoutId); } catch (Exception e) { e.printStackTrace(); } } } }
相关文章推荐
- Java自定义注解(annotation)基本使用
- Java中的Annotation详解和使用 自定义注解
- 【Annotation】使用自定义注解实现依赖注入
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
- Annotation注解的介绍和使用 自定义注解
- SpringBoot实践之(十五)---自定义注解Annotation的使用
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
- Annotation注解的介绍和使用 自定义注解
- 自定义注解Annotation的使用
- SpringMVC Annotation自定义注解使用笔记
- Annotation注解的介绍和使用 自定义注解
- 深入理解Java:注解(Annotation)基本概念、自定义注解、注解解析器
- 注解【介绍、基本Annotation、元Anntation、自定义注解、注入基本信息、对象】
- Annotation注解的介绍和使用 自定义注解
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
- Java自定义注解Annotation的使用
- 使用自定义AnnotationTransactionAttributeSource与TX:注解驱动
- 注解【介绍、基本Annotation、元Anntation、自定义注解、注入基本信息、对象】
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
- Java Annotation 注解的介绍和使用 自定义注解