一、什么是注解
java注解是从JDK5.0开始引入的新技术,注解可以理解为一种的程序特性的标注,该标注代表某一种功能,可在运行时反射来动态实现功能映射,也有作用于源码和字节码的。
注解是以“@注释名”在代码中存在的,例如:@Override //重写的注解
二、元注解
元注解是用于修饰其它注解的注解。 JDK5.0提供了四种元注解:@Target,@Retention,@Documented,@Inherted
元注解 | 描述 |
---|---|
@Target | 用于描述注解的使用范围(即:被描述的注解可以用在什么地方) |
@Retention | 表示需要在什么级别保存该注释信息,用于描述注解的生命周期 |
@Documented | 表示该注解将被包含在javadoc中 |
@Inherted | 表示子类可以继承父类中的该注解 |
2.1、@Target
用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
Target类型 | 描述 |
---|---|
ElementType.TYPE | 应用于类、接口(包括注解类型)、枚举 |
ElementType.FIELD | 应用于属性(包括枚举中的常量) |
ElementType.METHOD | 应用于方法 |
ElementType.PARAMETER | 应用于方法的形参 |
ElementType.CONSTRUCTOR | 应用于构造函数 |
ElementType.LOCAL_VARIABLE | 应用于局部变量 |
ElementType.ANNOTATION_TYPE | 应用于注解类型 |
ElementType.PACKAGE | 应用于包 |
ElementType.TYPE_PARAMETER | 应用于类型变量 |
ElementType.TYPE_USE | 应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型) |
2.2、@Retention
表明该注解的生命周期。(SOURCE < CLASS < RUNTIME)
Retention类型 | 描述 |
---|---|
RetentionPolicy.SOURCE | 只在源文件中有效,但会被编译器直接丢弃。 |
RetentionPolicy.CLASS | 在class文件中有效,但会被JVM加载时被丢弃。 |
RetentionPolicy.RUNTIME | 由JVM 加载,包含在类文件中,在运行时可以被获取到。 |
2.3、@Document
表示该注解将被包含在javadoc中,标记的元素会被Javadoc 或类似的工具文档化。
2.4、@Inherited
子类可以继承父类中的该注解。
三、自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
描述分析:
- @interface用来声明一个注解,格式:public @interface 注解名{定义内容}
- 其中的每一个方法实际上是声明一个配置参数
- 方法的名称就是参数名称
- 返回值类型就是参数的类型(返回值只能是基本类型,Class,String,enum)
- 可以通过default来声明参数的默认值
- 如果只是一个参数成员,一般参数名为value
- 注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值
修饰符: 访问修饰符必须为public,不写默认为pubic;
关键字: 关键字为@interface;
注解名称: 注解名称为自定义注解的名称,使用时还会用到;
注解内容: 注解中内容,对注解的描述。
四、案例演示
4.1、自定义注解
@Documented
@Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface InitValue {
String value() default "";
}
4.2、定义实体类并使用注解
@Data
public class InitEntity {
/**
* 姓名.
*/
private String name;
/**
* 年纪.
*/
private String age;
@InitValue(value = "张三")
public void setName(String name) {
this.name = name;
}
@InitValue(value = "18")
public void setAge(String age) {
this.age = age;
}
}
4.3、使用反射方式处理自定义注解
public class UserFactory {
public static InitEntity createEntity() {
InitEntity initEntity = new InitEntity();
Method[] methods = InitEntity.class.getMethods();
try {
for (Method method : methods) {
if (method.isAnnotationPresent(InitValue.class)) {
InitValue initValue = method.getAnnotation(InitValue.class);
method.invoke(initEntity, initValue.value());
}
}
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return initEntity;
}
}
4.4、运行代码
InitEntity entity = UserFactory.createEntity();
entity.setAge("20");
System.out.println(entity);
4.5、运行结果
name字段未进行set使用的是注解中的value,age字段重新赋了值。所以结果显示name=“张三”、age=“20”