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;
}
}
运行结果:

总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之际的更多内容!
相关文章
SpringBoot中实现Redis Stream队列的代码实例
本文介绍了如何在Spring Boot中使用Redis Stream队列进行消息的生产和消费,涉及到的主要内容包括添加Redis依赖、配置RedisTemplate、创建生产者和消费者监听器等,需要的朋友可以参考下2024-09-09
SpringBoot中MybatisX插件的简单使用教程(图文)
MybatisX 是一款基于 IDEA 的快速开发插件,方便在使用mybatis以及mybatis-plus开始时简化繁琐的重复操作,本文主要介绍了SpringBoot中MybatisX插件的简单使用教程,感兴趣的可以了解一下2023-06-06
源码阅读之storm操作zookeeper-cluster.clj
这篇文章主要介绍了源码阅读之storm操作zookeeper-cluster.clj的相关内容,对其源码进行了简要分析,具有参考意义,需要的朋友可以了解下。2017-10-10
idea运行java项目main方法报build failure错误的解决方法
当在使用 IntelliJ IDEA 运行 Java 项目的 main 方法时遇到 "Build Failure" 错误,这通常意味着在项目的构建过程中遇到了问题,以下是一些详细的解决步骤,以及一个简单的代码示例,用于展示如何确保 Java 程序可以成功构建和运行,需要的朋友可以参考下2024-09-09


最新评论