1 自定义注解
1.1 介绍
1.2 API说明
- ElementType:作用域,在下面类型的地方起作用,其他地方无效
- TYPE:允许被修饰的注解作用在类、接口和枚举上
- FIELD:允许作用在属性字段上
- METHOD:允许作用在方法上
- PARAMETER:允许作用在方法参数上
- CONSTRUCTOR:允许作用在构造器上
- LOCAL_VARIABLE:允许作用在本地局部变量上
- ANNOTATION_TYPE:允许作用在注解上
- PACKAGE:允许作用在包上
- RetentionPolicy:注解的生命周期
- SOURCE:当前注解编译期可见,不会写入 class 文件
- CLASS:类加载阶段丢弃,会写入 class 文件
- RUNTIME:永久保存,可以反射获取
- @Target:修饰对象范围
- 格式:@Target({ElementType.TYPE,ElementType,METHOD})
- @Retention:保留时间
- 格式:@Retention(RetentionPolicy.SOURCE)
- @Inherited:允许子类继承
-
1.3 使用
自定义注解格式:
public @interface 注解名{// 定义体}
获取注解信息
获取当前类上的注解
Class<?> aClass = Class.forName("com.mayikt.entity.UserEntity");MayiktName declaredAnnotation = aClass.getDeclaredAnnotation(MayiktName.class);System.out.println(declaredAnnotation);
获取当前方法上的注解
Method userNameMethod = aClass.getDeclaredMethod("getUserName");MayiktName declaredAnnotation = userNameMethod.getDeclaredAnnotation(MayiktName.class);System.out.println(declaredAnnotation);
获取字段上的注解
Field pubUserName = aClass.getDeclaredField("pubUserName");final MayiktName declaredAnnotation = pubUserName.getDeclaredAnnotation(MayiktName.class);System.out.println(declaredAnnotation);
获得构造方法注解
// 先获得构造方法对象Constructor<TestAnnotation> constructors = aClass.getConstructor(new Class[] {});MyConstructorAnnotation myConstructorAnnotation = constructors.getAnnotation(MyConstructorAnnotation.class);// 拿到构造方法上面的注解实例System.out.println(myConstructorAnnotation.desc() + "+" + myConstructorAnnotation.uri());
1.4 常用案例
1.4.1 获取字段描述与字段长度
自定义注解
@Target(ElementType.FIELD) // 注解用于字段上@Retention(RetentionPolicy.RUNTIME) // 保留到运行时,可通过注解获取public @interface MyFeild{/*** 描述字段作用*/String description();/*** 字段长度*/int length();}
实现注解和测试注解
public class AnnoTest {// 使用我们的自定义注解@MyField(description = "用户名", length = 12)private String username;@Testpublic void testMyField(){// 获取类模板Class c = AnnoTest.class;// 获取所有字段for(Field f : c.getDeclaredFields()){// 判断这个字段是否有MyField注解if(f.isAnnotationPresent(MyField.class)){// 拿到注解实例MyField annotation = f.getAnnotation(MyField.class);System.out.println("字段:[" + f.getName() + "], 描述:[" + annotation.description() + "], 长度:[" + annotation.length() +"]");}}}}
结果
1.4.2 获取类的描述和方法的描述
自定义注解
// 注解的作用域@Target({ElementType.METHOD, ElementType.TYPE})// 注解的生命周期@Retention(RetentionPolicy.RUNTIME)// 允许子类继承@Inherited// 生成javadoc的时候生成注解的信息@Documented// @interface:使用@interface关键定义注解public @interface Description {// 注解的成员// 成员类型所限的,合法的类型包括原始数据类型及String、Class、Annotation、EnumerationString desc();String author();// 成员以无参无异常方式生命,可以用default为成员指定一个默认值int age() default 18;// 如果注解成员只有一个时,成员名必须取名未value(),在使用时可以忽略成员名和赋值号(=)// 注解可以没有成员,没有成员的注解成为标识注解}
调用注解 ```java @Description(desc=”I am class annotation”, author=”hd”) public class TestDescription {
@Description(desc=”I am method annotation”, author=”hd”) public String test(){
return "red";
}
}
- 实现注解```java/*** 解析注解* 通过反射获取类,函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑** 对于一个类或者接口来说,Class 类中提供了以下一些方法用于反射注解。getAnnotation:返回指定的注解isAnnotationPresent:判定当前元素是否被指定注解修饰getAnnotations:返回所有的注解getDeclaredAnnotation:返回本元素的指定注解getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的** @author H__D* @date 2019-07-09 22:52:42**/public class ParseDecription {public static void main(String[] args) {// TODO Auto-generated method stub// 1、使用类加载器加载类try {Class c = Class.forName("com.xkcoding.test.TestDescription");System.out.println(c);// 2、找到类上面的注解boolean isExist = c.isAnnotationPresent(Description.class);if(isExist) {// 3、拿到注解实例Description d = (Description) c.getAnnotation(Description.class);System.out.println("========parse class annotation=========");System.out.println("desc = " + d.desc());System.out.println("author = " + d.author());System.out.println("age = " + d.age());}// 4、找到方法上的注解Method[] ms = c.getMethods();for (Method m : ms) {boolean isMExist = m.isAnnotationPresent(Description.class);if(isMExist) {Description d = m.getAnnotation(Description.class);System.out.println("========parse method annotation=========");System.out.println("desc = " + d.desc());System.out.println("author = " + d.author());System.out.println("age = " + d.age());}}// 另外一种解析方法for (Method m : ms) {Annotation[] annotations = m.getAnnotations();for (Annotation annotation : annotations) {if(annotation instanceof Description) {System.out.println("========parse method annotation other way=========");Description d = (Description) annotation;System.out.println("desc = " + d.desc());System.out.println("author = " + d.author());System.out.println("age = " + d.age());}}}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
- 结果
2 常用注解
- @Override:表示方法重写。
- @Deprecated:表示过时的方法。
- @SuppressWarnings:表示忽略警告。
