Java注解原理

文章详细介绍了Java中的元注解,如@Target、@Retention、@Documented和@Inherited的作用和用法。同时,探讨了注解的解析方式,包括编译期间的扫描和运行时的反射机制,并通过示例代码展示了如何通过反射获取和使用注解信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一):java元注解

java的最基本的几个注解主要有一下几个

@Target:该注解主要是作用在方法,属性,类等上
@Retention:主要有三个参数

  1.         SOURCE:当前注解编译器可见,但是不会写入到class文件
  2.         CLASS:类加载阶段会丢弃,但是会写入到class文件
  3.         RUNTIME:永久保存下来

@Documented:注解是否应当被包含在 JavaDoc 文档中,通常不用,作用不是很大
@Inherited:是否允许子类继承该注解

(二):注解原理

java当中所有的注解都是实现了Annotation这个接口,如下图所示,

(三):注解解析

一个注解解析通常有两种方式:

编译期间直接进行扫描:根据注解的名字,来判断才程序应该做什么事情,比方说spring的注解component注解的源码如下,

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	String value() default "";

}

spring是通过注解的名称来判断,spring应该对这个对象做什么事情,(实际上,是spring底层源码,通过识别注解的名字来判断的)

通过运行期间来进行反射 :

一个注解,实际上也是一个对象,所以的话,我们也可以通过java的反射机制来获取注解里面的相关内容,不多说,代码如下,

//运行在字段上的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetField {

    String value() default "我是定义在字段上的注解";
}

//运行在方法上的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetMethod {
    String value() default "我是定义在方法上的注解";
}

//运行在参数上的注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetParameter {
    String value() default "我是定义在一个参数上的注解";
}

//运行在类上的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnTargetType {
    String value() default "我是定义在类上的注解";
}

//测试类
@MyAnTargetType
public class AnnotationTest {

    @MyAnTargetField
    private String field="我是字段";

    @MyAnTargetMethod
    public void test(@MyAnTargetParameter String args)
    {
        System.out.println("参数值sdfsdf"+args);
    }
    public static void main(String[] args) {
        // 获取类上的注解MyAnTargetType
        MyAnTargetType t = AnnotationTest.class.getAnnotation(MyAnTargetType.class);
        System.out.println("类上的注解值 === "+t.value());
        MyAnTargetMethod tm = null;
        try {
            // 根据反射获取AnnotationTest类上的test方法
            Method method = AnnotationTest.class.getDeclaredMethod("test",String.class);
            // 获取方法上的注解MyAnTargetMethod
            tm = method.getAnnotation(MyAnTargetMethod.class);
            System.out.println("方法上的注解值 === "+tm.value());
            // 获取方法上的所有参数注解  循环所有注解找到MyAnTargetParameter注解
            Annotation[][] annotations = method.getParameterAnnotations();
            for(Annotation[] tt : annotations){
                for(Annotation t1:tt){
                    if(t1 instanceof MyAnTargetParameter){
                        System.out.println("参数上的注解值 === "+((MyAnTargetParameter) t1).value());
                    }
                }
            }
            method.invoke(new AnnotationTest(), "改变默认参数");
            // 获取AnnotationTest类上字段field的注解MyAnTargetField
            MyAnTargetField fieldAn = AnnotationTest.class.getDeclaredField("field").getAnnotation(MyAnTargetField.class);
            System.out.println("字段上的注解值 === "+fieldAn.value());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行结果如下所示

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值