JAVA自定义注解详情
原理:
注解的本质是继承Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象Proxy1,通过动态代理对象,调用自定义注解(接口)的方法,最终会调用AnnotationInvocationHandler 的invoke方法.
元注解:
- @Documented:是否将注解包含到JavaDoc中
- @Retention:什么时候使用该注解,表明注解的生命周期
- @Target:注解用于什么地方
- @Inherited:是否允许子类继承改注解
@Retention参数讲解:
RetentionPolicy.SOURCE:
在编译阶段丢弃,这些注解在编译结束后就不会再有意义,所以它不会写入字节码.比如@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS:
在类加载的时候丢弃, 包含在类文件中
RetentionPolicy.RUNTIME:
包含在类文件中,在运行时可以被获取到
@Target:参数讲解:
ElementType.TYPE
:用于类,接口,枚举
ElementType.FIELD
:应用于属性
ElementType.METHOD
:应用于方法
ElementType.PARAMETER
:用于方法的形式参数
ElementType.CONSTRUCTOR
:用于构造函数
ElementType.LOCAL_VARIABLE
:应用于局部变量
ElementType.ANNOTATION_TYPE
:应用于注解类型
ElementType.PACKAGE:
应用于包
ElementType.TYPE_PARAMETER
:应用于类型变量(1.8新增)
ElementType.TYPE_USE
:1.8版本新增,应用于任何使用类型的语句中
案例:
给一个类的String属性设置默认值
@Documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ObjectFlag { //默认值 String value() default "默认值1"; }
public class ObjectTest { @ObjectFlag String name; @ObjectFlag Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }
public class ObjectRun { public static <T> T setValueField(T t) throws IllegalAccessException { Class<?> cls = t.getClass(); Field[] fields = cls.getDeclaredFields(); for (Field field : fields) { boolean hasConfigField = field.isAnnotationPresent(ObjectFlag.class); field.setAccessible(true);//设置可以访问私有变量 //若属性上有注解,使用注解的值作为key去配置文件中查找 if (hasConfigField) { //获取注解的默认值 Object annoValue = field.getAnnotation(ObjectFlag.class).value(); System.out.println("当前的属性名称为:" + field.getName()); System.out.println("当前属性类型:" + field.getGenericType().toString()); //获取到属性的数据类型 String type = field.getGenericType().toString(); if (type.endsWith("String")) {//如果是字符串类型 field.set(t, annoValue.toString()); } } else { //若属性上没有注解,则使用属性名作为key去配置文件中查找 System.out.println("属性" + field.getGenericType().toString() + "没有该注解"); } } return t; } }
运行结果:
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之际的更多内容!
相关文章
mybatis自定义类型处理器TypehHandler示例详解
我们在写mapper映射器的配置文件时,不经意间已经用到类型转换,不过是mybatis帮我们完成的,下面这篇文章主要给大家介绍了关于mybatis自定义类型处理器TypehHandler的相关资料,需要的朋友可以参考下2018-09-09详解Java LinkedHashMap与HashMap的使用
这篇文章主要通过几个示例为大家详细介绍了Java中LinkedHashMap与HashMap的常见使用和概述,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下2022-10-10使用Springboot+poi上传并处理百万级数据EXCEL
这篇文章主要介绍了使用Springboot+poi上传并处理百万级数据EXCEL,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-12-12spring @Cacheable扩展实现缓存自动过期时间及自动刷新功能
用过spring cache的朋友应该会知道,Spring Cache默认是不支持在@Cacheable上添加过期时间的,虽然可以通过配置缓存容器时统一指定,本文主要介绍了如何基于spring @Cacheable扩展实现缓存自动过期时间以及缓存即将到期自动刷新,2024-02-02Springboot容器级后置处理器BeanDefinitionRegistryPostProcessor
这篇文章主要介绍了Springboot容器级后置处理器BeanDefinitionRegistryPostProcessor,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧2023-01-01Elasticsearch查询及聚合类DSL语句宝典示例详解
这篇文章主要为大家介绍了Elasticsearch查询及聚合类DSL语句宝典示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-01-01
最新评论