Java的注解,走进Android架构

  • 使用注解的元素
  • 操作注解使其起作用(注解处理器)

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1,通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法,该方法会从memberValues这个Map中索引出对应的值,而memberValues的来源是Java常量池。

四、Java内置的注解

============

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解:

@Override  检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。

@Deprecated 标记过时方法。如果使用该方法,会报编译警告。

@SuppressWarnings 指示编译器去忽略注解中声明的警告。例如使用@SuppressWarnings(“unchecked”)可以忽略空字符带来的编译警告。

java.lang.annotation提供了四种元注解,专门注解其他的注解:

@Retention 定义该注解的生命周期

  • RetentionPolicy.SOURCE :在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码,@Override, @SuppressWarnings都属于这类注解。
  • RetentionPolicy.CLASS :在类加载的时候丢弃。在字节码文件的处理中有用,注解默认使用这种方式
  • RetentionPolicy.RUNTIME :始终不会丢弃。运行期也保留该注解,因此可以使用反射机制读取该注解的信息,我们自定义的注解通常使用这种方式。

@Documented 一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。

@Target 表示该注解的作用域(用于什么地方)。可用的ElementType参数包括:

  • ElementType.CONSTRUCTOR :用于描述构造器
  • ElementType.FIELD :成员变量、对象、属性(包括enum实例)
  • ElementType.LOCAL_VARIABLE :用于描述局部变量
  • ElementType.METHOD :用于描述方法
  • ElementType.PACKAGE :用于描述包
  • ElementType.PARAMETER :用于描述参数
  • ElementType.TYPE :用于描述类、接口(包括注解类型) 或enum声明

@Inherited 定义该注释和子类的关系。 @Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

java7 新添加1个注解:

@SafeVarargs Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。

java8 新添加2个注解:

@FunctionalInterface Java 8 开始支持,标识一个匿名函数或函数式接口。

@Repeatable Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

五、java自定义注解

============

自定义注解类编写的一些规则:

1. Annotation类型定义为@interface,所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口;

2. 参数成员只能用public或默认(default)这两个访问权修饰;

3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组;

4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法;

5. 注解也可以没有定义成员,不过这样注解就没啥用了;

6.自定义注解需要使用到元注解;

【自定义注解实例】

水果名称注解接口:FruitName.java

import java.lang.annotation.Documented;

import java.lang.annotation.Retention;

import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**

  • 水果名称注解接口

  • 使用“元注解”进行相关声明

*/

@Target(FIELD)//注解的作用域:成员变量、对象、属性(包括enum实例)

@Retention(RUNTIME)//注解的生命周期:始终不会丢弃

@Documented//将注解信息添加在java文档中

public @interface FruitName {

String value() default “”;

}

水果颜色注解接口:FruitColor.java

import java.lang.annotation.Documented;

import java.lang.annotation.Retention;

import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**

  • 水果颜色注解接口

*/

@Target(FIELD)

@Retention(RUNTIME)

@Documented

public @interface FruitColor {

/**

  • 颜色枚举

*/

public enum Color{ 红色,绿色};

/**

  • 颜色默认属性

*/

Color fruitColor() default Color.绿色;

}

水果供应者注解接口:FruitProvider.java

import java.lang.annotation.Documented;

import java.lang.annotation.Retention;

import java.lang.annotation.Targe

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

t;

import static java.lang.annotation.ElementType.FIELD;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**

  • 水果供应者注解接口

*/

@Target(FIELD)

@Retention(RUNTIME)

@Documented

public @interface FruitProvider {

/**

  • 供应商编号

*/

public int id() default -1;

/**

  • 供应商名称

*/

public String name() default “”;

/**

  • 供应商地址

*/

public String address() default “”;

}

注解处理器(反射机制):FruitInfoUtil.java

import java.lang.reflect.Field;

/**

  • 注解处理器(反射机制)

*/

public class FruitInfoUtil {

public static void getFruitInfo(Class<?> clazz){

String strFruitName=“水果名称:”;

String strFruitColor=“水果颜色:”;

String strFruitProvicer=“供应商信息:\r\n”;

Field[] fields = clazz.getDeclaredFields();

for(Field field :fields){

if(field.isAnnotationPresent(FruitName.class)){

FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);

strFruitName=strFruitName+fruitName.value();

System.out.println(strFruitName);

}

else if(field.isAnnotationPresent(FruitColor.class)){

FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);

strFruitColor=strFruitColor+fruitColor.fruitColor().toString();

System.out.println(strFruitColor);

}

else if(field.isAnnotationPresent(FruitProvider.class)){

FruitProvider fruitProvider= (FruitProvider) field.getAnnotation(FruitProvider.class);

strFruitProvicer=strFruitProvicer+“供应商编号:”+fruitProvider.id()+" 供应商名称:"+fruitProvider.name()+" 供应商地址:"+fruitProvider.address();

System.out.println(strFruitProvicer);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值