- 使用注解的元素
- 操作注解使其起作用(注解处理器)
注解本质是一个继承了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);
}
}