当前位置:首页 > 技术 > 正文内容

Java 自定义注解的定义与运行时解析机制

访客 技术 2026年8月30日 3

元注解(Meta-Annotations)基础

在 Java 中,自定义注解的实现依赖于元注解。元注解是用于标注其他注解的特殊注解,java.lang.annotation 包中提供了四种核心元注解:

  • @Retention:指定注解的生命周期。
    • RetentionPolicy.SOURCE:仅保留在源码阶段,编译后丢弃。
    • RetentionPolicy.CLASS:保留在字节码文件中,但运行时无法通过反射获取(默认行为)。
    • RetentionPolicy.RUNTIME:始终保留,运行时可以通过反射机制读取,这是开发自定义功能最常用的模式。
  • @Target:定义注解可以应用的程序元素类型,例如 ElementType.FIELD(字段)、ElementType.METHOD(方法)、ElementType.TYPE(类或接口)等。
  • @Documented:标记该注解是否应包含在生成的 JavaDoc 文档中。
  • @Inherited:指示被标注的类,其子类会自动继承该注解。

定义自定义注解

以下示例通过模拟电子产品元数据管理,展示如何定义不同类型的注解:


// 定义产品品牌注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BrandName {
    // 默认属性名为 value,使用时可省略 key
    String value() default "";
}

// 定义产品分类注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DeviceCategory {
    public enum Category { PC, MOBILE, WEARABLE };
    Category type() default Category.PC;
}

// 定义供应商详细信息注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface VendorInfo {
    int code() default -1;
    String provider() default "Unknown";
    String location() default "Mainland China";
}

在实体类中应用注解

将定义好的注解应用到具体的业务模型字段上:


public class Computer {

    @BrandName("ThinkPad")
    private String modelName;

    @DeviceCategory(type = DeviceCategory.Category.PC)
    private String category;

    @VendorInfo(code = 1024, provider = "Lenovo Group", location = "Beijing")
    private String manufacturer;

    // Getter 和 Setter 方法省略
}

运行时解析注解

核心逻辑在于通过 Java 反射 API 获取字段上的注解实例,并提取其属性值:


import java.lang.reflect.Field;

public class MetadataProcessor {

    public static void parseDeviceMetadata(Class<?> clazz) {
        // 获取类中声明的所有字段
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            // 解析 BrandName 注解
            if (field.isAnnotationPresent(BrandName.class)) {
                BrandName brand = field.getAnnotation(BrandName.class);
                System.out.println("品牌名称: " + brand.value());
            } 
            // 解析 DeviceCategory 注解
            else if (field.isAnnotationPresent(DeviceCategory.class)) {
                DeviceCategory category = field.getAnnotation(DeviceCategory.class);
                System.out.println("设备分类: " + category.type());
            } 
            // 解析 VendorInfo 注解
            else if (field.isAnnotationPresent(VendorInfo.class)) {
                VendorInfo vendor = field.getAnnotation(VendorInfo.class);
                System.out.println("供应商代码: " + vendor.code() + 
                                   ", 名称: " + vendor.provider() + 
                                   ", 所在地: " + vendor.location());
            }
        }
    }

    public static void main(String[] args) {
        parseDeviceMetadata(Computer.class);
    }
}

通过这种方式,我们可以在运行时动态获取类元数据。这种机制是 Spring 依赖注入(DI)和面向切面编程(AOP)等核心功能的基础。通过反射处理注解,开发者可以实现高度解耦的业务逻辑,例如权限控制、日志记录或自动化数据校验。

标签: Java

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。