第七篇 java的注解以及使用反射实现自定义注解功能

Java 注解的基本概念

Java 注解(Annotation)是一种元数据形式,用于为代码提供附加信息。注解不会直接影响代码逻辑,但可以通过反射或编译时处理工具(如注解处理器)读取并执行特定操作。

注解的常见用途

  • 代码检查 :如 @Override 标注方法重写,编译器会检查是否正确覆盖父类方法。
  • 生成代码 :如 Lombok 的 @Data 自动生成 getter/setter。
  • 配置替代 :如 Spring 的 @Autowired 实现依赖注入。

内置注解

Java 提供了一些内置注解:

  • @Override:标记方法重写。
  • @Deprecated:标记已过时的类或方法。
  • @SuppressWarnings:抑制编译器警告(如 @SuppressWarnings("unchecked"))。

元注解

Java元注解是用于定义其他注解的特殊注解,位于java.lang.annotation包中,主要包含以下五种核心元注解:

注解名称 作用描述 引入版本 典型参数/使用示例
‌**@Target**‌ 表示该注解类型的所使用的程序元素类型。当注解类型声明中没有@Target元注解,则默认为可适用所有的程序元素。如果存在指定的@Target元注解,则编译器强制实施相应的使用限制。关于程序元素(ElementType)是枚举类型,共定义8种程序元素 Java 5 ElementType枚举值: TYPE FIELD METHOD PARAMETER
‌**@Retention**‌ 表示该注解类型的注解保留的时长。当注解类型声明中没有@Retention元注解,则默认保留策略为RetentionPolicy.CLASS。关于保留策略(RetentionPolicy) Java 5 RetentionPolicy值: SOURCE CLASS RUNTIME
‌**@Documented**‌ 表示拥有该注解的元素可通过javadoc此类的工具进行文档化。该类型应用于注解那些影响客户使用带注释(comment)的元素声明的类型。如果类型声明是用Documented来注解的,这种类型的注解被作为被标注的程序成员的公共API。 Java 5 无参数
‌**@Inherited**‌ 表示该注解类型被自动继承,如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类 Java 5 仅对类注解有效
‌**@Repeatable**‌ 表示允许同一个注解在同一个位置多次使用。在Java 8之前,同一个注解不能在同一个位置重复使用 Java 8 需要容器注解配合: @Repeatable(Schedules.clas

自定义注解

Java自定义注解是通过@interface关键字定义的元数据形式,本质上是一种特殊接口,继承自java.lang.annotation.Annotation。与内置注解不同,自定义注解允许开发者根据项目需求创建特定功能的标记。

自定义注解的主要特点:

  • 不直接影响程序逻辑,但可通过编译检查或反射机制处理

  • 可附加在类、方法、字段等元素上提供补充信息

  • 通过元注解控制其行为特征

上案例

新建一个注解类,使用@interface进行定义

java 复制代码
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Deprecated
public @interface MyAnnotation {
    String value() default "";
}
使用反射读取注解中的数据,模拟实现注解功能

1.实体类

java 复制代码
@Data
@Component
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @Value("123123")
    private Integer uid;
    @Value("李狗蛋")
    private String username;
    @Value("20")
    private Integer age;
    @Autowired
    private Cat cat;
}

2.测试类

java 复制代码
public class testAnntation {
    public static void main(String[] args) throws IllegalAccessException {
        Student student = new Student();
        //获取反射字节码
        Class clazz = student.getClass();
        //拿到实体类中的所以字段
        Field[] fiels = clazz.getDeclaredFields();
        for (Field f :fiels) {

            //获取注解
            MyAnnotation annotation = f.getAnnotation(MyAnnotation.class);

            if (annotation!=null){
                String value = annotation.value();//获取注解的值
                //设置暴力访问
                f.setAccessible(true);
                f.set(student,value);//进行注入,实现赋值
            }
        }
        System.out.println(student);
    }
}
相关推荐
cpp_learners7 分钟前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
开发语言·c++·责任链模式
2301_322414280414 分钟前
活力孕康复APP 47737- 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·mysql·微信小程序·idea·微信开发者工具
君顾118 分钟前
外卖CPS软件开发实战:从系统架构到部署全流程指南
java·开发语言·外卖
AIFQuant37 分钟前
Python实时外汇行情接入实战:WebSocket与REST K线查询
开发语言·python·websocket
vx_Biye_Design1 小时前
springboot游泳馆系统93765-计算机课程设计、毕业设计
java·javascript·spring boot·后端·python·spring·课程设计
名字还没想好☜1 小时前
Java NIO ByteBuffer 实战:flip/clear/compact 三个绕晕人的方法与 position/limit 心智模型
java·开发语言·后端·spring·nio
Wang's Blog1 小时前
Java框架快速入门: Spring Security+OAuth2之短信服务多供应商动态切换(阿里云与LeanCloud)
java·spring·阿里云
Doubbbbbbble云1 小时前
区间合并问题的常见算法模式与优化思路4
java·数据结构·算法
小溪学编程2 小时前
AQS 原理详解:从 CLH 队列到 ReentrantLock 的实现
java·开发语言
持敬chijing2 小时前
Web前后端开发-JavaScript 入门教程
开发语言·前端·javascript