Java注解实现以及部分参数说明

本文深入探讨了Java注解的底层实现原理,解释了注解如何通过反射技术实现在程序运行时获取配置信息。文章详细介绍了注解的组成部分,包括Annotation、ElementType、RetentionPolicy,并对元注解如@Target、@Retention、@Documented、@Inherited进行了说明。

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

Java注解详细说明

今天面试过程中遇到了一个问题:谈谈注解的底层实现。由于本人只写过几个自定义注解,在复习过程中也忽略了这一部分,所以只回答了使用过一些自定义注解。然后面试官又问了一些反射的问题。面试结束经过百度后才知道,注解的底层实现就是用到了反射。所以今天来补上这一部分内容。

首先,注解是没有行为的,只能有数据。让其实现某些行为必须有实例(也就是代理对象),再用反射技术实现某些行为。

通过对一个注解进行反编译,我们可以在反编译代发中发现 public interface extends java.lang.annotation.Annotation ,我们可以得知,注解就是一个继承自java.lang.annotation.Annotation的接口。也就是说,注解就是一个接口。

那么接口又是怎么样设置的属性呢?简单来说就是Java通过动态代理的方式来生成了一个接口的实例。这样对该代理的实例的属性赋值后,我们就可以通过反射,在程序运行时获取到注解的配置信息了。

下面再来看一块代码

@Override
public String toString() {
     return "xxxxx";
}

上面的代码重写了toString方法并使用了@Override注解。但是即使它不使用此注解,程序也会正常执行。

所以注解也称为源代码的元数据。也就是说他只是一个附带品而已,它本身没有任何作用,只有外部程序(编译器或VM)解析它,才会引起它的作用。比如@Override的作用是告诉编译器这个方法是一个重写方法(描述方法的元数据),如果父类中不存在该方法,编译器便会报错,提示该方法没有重写父类中的方法。如果不小心拼写错误,例如将toString()写成了toStrring(){double r},而且没有使用@Override注解,那程序依然能编译运行。但实际的执行结果肯定与预期不符。这也是注解的一大功能,就是有助于程序的阅读,

一个注解基本由AnnotationElementTypeRetentionPolicy三个类组成,Annotation是接口,其余两个是枚举。 所有的注解都基于这三个类,所谓的元注解也是用这三个类生成的,只不过可修饰的元素(ElementType)为ANNOTATION_TYPE。

下面简要的介绍一下元注解

元注解就是用来描述注解的注解,比如“@Target”元注解,它的作用是用来说明MethodInfo这个注解只能用于对方法进行注解:

@Target(ElementType.METHOD)
public @interface MethodInfo { 
    ...
}

1. Retention

这个元注解表示一个注解会被保留到什么时候,比如以下代码表示Developer注解会被保留到运行时(也就是说在运行时依然能发挥作用):

@Retention(RetentionPolicy.RUNTIME)
public @interface Developer {
    String value();
}

我们在使用@Retention时,后面括号里的内容即表示它的取值,从以上定义我们可以看到,取值的类型为RetentionPolicy,这是一个枚举类型,它可以取以下值:

  • SOURCE:表示在编译时这个注解会被移除,不会包含在编译后产生的class文件中;

  • CLASS:表示这个注解会被包含在class文件中,但在运行时会被移除;

  • RUNTIME:表示这个注解会被保留到运行时,在运行时可以JVM访问到,我们可以在运行时通过反射解析这个注解。

2. Documented

当一个注解被@Documented元注解所修饰时,那么无论在哪里使用这个注解,都会被Javadoc工具文档化。

3. Inherited

表明被修饰的注解类型是自动继承的。如果你想让一个类和它的子类都包含某个注解,就可以使用@Inherited来修饰这个注解。也就是说,假设Parent类是Child类的父类,那么我们若用被@Inherited元注解所修饰的某个注解对Parent类进行了修饰,则相当于Child类也被该注解所修饰了。

4. Target

这个元注解说明了被修饰的注解的应用范围,也就是被修饰的注解可以用来注解哪些程序元素,ElementType是一个枚举类型,它可以取以下值:

  • TYPE:表示可以用来修饰类、接口、注解类型或枚举类型;
  • PACKAGE:可以用来修饰包;
  • PARAMETER:可以用来修饰参数;
  • ANNOTATION_TYPE:可以用来修饰注解类型;
  • METHOD:可以用来修饰方法;
  • FIELD:可以用来修饰属性(包括枚举常量);
  • CONSTRUCTOR:可以用来修饰构造器;
  • LOCAL_VARIABLE:可用来修饰局部变量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值