注解是Java 1.5 引入的,目前已被广泛应用于各种Java
框架,如Hibernate,Jersey,Spring。注解相当于是一
种嵌入在程序中的 元数据 ,可以使用注解解析工具或编
译器对其进行解析,也可以指定注解在编译期或运行期
有效。在注解诞生之前,程序的元数据存在的形式仅限
于java注释或javadoc,但注解可以提供更多功能,它不
仅包含元数据,还能作用于运行期,注解解析器能够使
用注解决定处理流程。
Annotation(注解)就是Java提供了一种元程序中的元素关
联任何信息和任何元数据 (metadata)的途径和方法。
Annotation是一个接口,程序可以通过反射来获取指定
程序元素的Annotation对象,然后通过Annotation对象来
获取注解里面的元数据。注解API非常强大,被广泛应用
于各种Java框架。
根据注解参数的个数分类
1)、标记注解:一个没有成员定义的Annotation类型被 称为标记注解。 2)、单值注解:只有一个值 3)、完整注解:拥有多个值 根据注解使用方法和用途分类 1)、JDK内置系统注解 2)、元注解 3)、自定义注解@interface:用来声明一个注解。注解类里的每一个方法
实际上是声明了一个配置参数。方法的名称就是参数的
名称,返回值类型就是参数的类型。可以通过default来
声明参数的默认值。
package com.lwf.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author lwf * @title: MyAnnotation * @projectName ReflectLearn * @description: TODO * @date 2020/10/2216:44 */ @Target({ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { public String name() default "注解"; public int value() default 0; }CONSTRUCTOR:用于描述构造器
FIELD:用于描述域
LOCAL_VARIABLE:用于描述局部变量
METHOD:用于描述方法
PACKAGE:用于描述包
PARAMETER:用于描述参数
TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的 生命周期 存放枚举类型 RetentionPoicySOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在运行时有效(即运行时保留)
@Documented :表示使用该注解的元素应被javadoc或类似工具文档化, 它应用于类型声明,类型声明的注解会影响客户端对注 解元素的使用。 @Inherited :表示一个注解类型会被自动继承,如果用户在类声明的 时候查询注解类型,同时类声明中也没有这个类型的注 解,那么注解类型会自动查询该类的父类,这个过程将 会不停地重复,直到该类型的注解被找到为止,或是到 达类结构的顶层(Object)。定义注解
package com.lwf.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author lwf * @title: MyAnnotationPlus * @projectName ReflectLearn * @description: TODO * @date 2020/10/2217:47 */ @Target({ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotationPlus { public String value() default "lwf"; }2.定义javabean并使用以上注解 MyAnnotationPlus
package com.lwf.annotation; /** * @author lwf * @title: Student * @projectName ReflectLearn * @description: TODO * @date 2020/10/2217:49 */ public class Student { private int id; @MyAnnotationPlus private String name; @MyAnnotationPlus("上饶") private String city; public Student() { } public Student(int id) { this.id = id; } public Student(int id, String name, String city) { this.id = id; this.name = name; this.city = city; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", city='" + city + '\'' + '}'; } }定义解析器,将注解中的值通过反射将值给pojo类
package com.lwf.annotation; import java.lang.reflect.Field; /** * @author lwf * @title: LearnPlus * @projectName ReflectLearn * @description: 解析 将 MyAnnotationPlus接口值给Student的属性 * @date 2020/10/2217:51 */ public class LearnPlus<T> { public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException { Student student=Student.class.newInstance(); new LearnPlus<Student>().getObject("com.lwf.annotation.Student",student); System.out.println(student); } /** * MyAnnotationPlus注解解析器 * @param str * @param obj * @return * @throws ClassNotFoundException * @throws IllegalAccessException */ public boolean getObject(String str,T obj) throws ClassNotFoundException, IllegalAccessException { Class c= Class.forName(str); for (Field field : c.getDeclaredFields()) { if(field.isAnnotationPresent(MyAnnotationPlus.class)){ field.setAccessible(true); if(field.get(obj)==null){ field.set(obj, field.getAnnotation(MyAnnotationPlus.class).value()); } } } return true; } }