You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java注解逻辑位置、差异化机制及自定义方法咨询

Java注解核心问题解答

一、注解逻辑实现的位置

注解本身只是元数据标记,没有自带逻辑。它的功能实现分两类场景:

  • 编译期逻辑:由注解处理器(Annotation Processor)执行,比如编译器内置处理器处理@Override,第三方框架的处理器处理JPA、Lombok等注解,这类逻辑在编译阶段完成,生成字节码或做语法校验。
  • 运行期逻辑:通过Java反射API读取注解信息,由业务代码或框架逻辑执行,比如Spring、JPA在程序运行时扫描注解,触发依赖注入、ORM映射等操作。

二、结构相同的注解差异在哪里

两个结构相似的注解,核心差异体现在两点:

  1. 元注解配置:元注解(@Retention、@Target等)决定了注解的生命周期、作用目标、是否可继承等属性,这是注解功能的基础。
  2. 语义与配套逻辑:不同注解被不同的工具/框架识别,绑定了完全不同的处理逻辑——注解的名字本身就是一种语义约定,工具会根据注解名执行对应的逻辑。

以@Id、@Override、@Embeddable为例,它们的源码结构(interface定义)看似一致,但本质差异极大:

  • @Override:元注解是@Retention(SOURCE),仅在编译期有效。编译器会在编译时检查被标记的方法是否真的重写了父类方法,编译完成后该注解会被直接丢弃,不会进入字节码。
  • @Id:元注解是@Retention(RUNTIME),运行时可被反射读取。JPA框架在运行时扫描实体类,将标记@Id的字段识别为主键,自动生成主键映射的SQL逻辑。
  • @Embeddable:同样是@Retention(RUNTIME)级别,但JPA会将标记的类视为嵌入式组件,把类中的字段直接映射到宿主实体的数据库表字段中,而非单独生成表。

三、无法查看逻辑代码时,如何创建自定义注解

按以下步骤落地:

  1. 明确注解用途:先确定是做编译期校验/代码生成,还是运行时的逻辑触发(比如日志、权限校验)。
  2. 定义注解类:用@interface关键字声明,搭配必要的元注解:
    • @Retention:指定生命周期(SOURCE仅编译期、CLASS字节码保留、RUNTIME运行时可反射)
    • @Target:指定可标记的元素(METHOD、FIELD、TYPE等)
    • 可选@Documented(生成Javadoc时包含)、@Inherited(子类可继承父类注解)
  3. 实现处理逻辑:
    • 编译期场景:编写继承AbstractProcessor的处理器,注册到META-INF/services/javax.annotation.processing.Processor,在process方法中处理注解,完成代码生成或语法校验。
    • 运行期场景:用反射API(如Class.getAnnotations()、Method.getAnnotation())扫描带有自定义注解的元素,编写对应的业务逻辑触发代码。
  4. 测试验证:将注解标记到目标元素上,编译或运行程序,验证是否达到预期效果。

举个简单的运行时自定义注解示例:

// 自定义注解
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogMethod {
    String value() default "执行方法";
}

// 注解处理逻辑
public class LogProcessor {
    public static void process(Object obj) throws Exception {
        for (var method : obj.getClass().getDeclaredMethods()) {
            LogMethod logAnno = method.getAnnotation(LogMethod.class);
            if (logAnno != null) {
                System.out.println(logAnno.value() + ": " + method.getName());
                method.invoke(obj);
            }
        }
    }
}

// 注解使用
public class Test {
    @LogMethod("调用测试方法")
    public void test() {
        System.out.println("方法执行中");
    }

    public static void main(String[] args) throws Exception {
        LogProcessor.process(new Test());
    }
}

内容的提问来源于stack exchange,提问作者v0ld3m0rt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 08:18:25