栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java注解究竟是如何起作用的及注解的基本概念

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java注解究竟是如何起作用的及注解的基本概念

注解是如何实现的

ps:由于时间有限来不及看太详细,所以只写个大概,后面有机会会进行详细补全。

疑问的起点

以前在写代码的时候就看过一些注解的源码,每次点进去看的时候发现都只有简简单单几行代码,但是为什么就可以实现一些非常复杂的功能呢?哪个时候还不太在意,今天在写代码的时候,看到了@Slf4j的注解,突然想看看它的源码是什么,然后点进去一看

//  
// Source code recreated from a .class file by IntelliJ IDEA  
// (powered by FernFlower decompiler)  
//  
  
package lombok.extern.slf4j;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Retention(RetentionPolicy.SOURCE)  
@Target({ElementType.TYPE})  
public @interface Slf4j {  
    String topic() default "";  
}

这就是所有的代码,还是一如既往的简单,再去看了其他的注解依然如此,那么究竟靠什么来实现对应的功能呢?

注解如何起作用 注解与接口

注解实际上就是一个标签,我们在一个某一类事物打标签的时候也是尽量越简单越好,所以注解就是这么回事,它仅仅是一个标签,其代码结构如下:

public @interface 注解名称{
    属性列表
;
}

仅仅是注解名字加上注解的一些属性,然后我们又注意到,它的定义方式是
@interface
interface我们都知道,是一个接口,那么猜测注解的本质上类似接口,所以注解才会如此简单,因为接口也是如此仅仅定义方法而不去实现,想到这一层之后脑子里突然明朗起来。

注解与反射

为什么都说注解实际上就是使用反射实现的,我们已经看过了注解里面的东西,就这么一点,与反射有什么关系呢?但是大家都说注解就是用反射实现的自然有其的道理。
如果自己使用过一些反射代码,就会留意到有这么一个方法:

xxx.getAnnotation(annotation.class)

xxx代表着一个对象,annotation.class代表一个注解的class,我们可以通过这个方法来获取一个类上相应的注解。
还可以直接判断一个对象上是否使用了某某注解:

 xxx.isAnnotationPresent(annotation.class)

至此我们应该已经想到了一个注解对应的功能是如何实现的了。

    当我们注明一个注解的时候,只是制造出了一个标签当我们给一个类加上注解的时候,就是给这个对象贴上了某个标签然后实现一个方法:通过反射得到一个对象,然后判断对象上是否有此注解,如果有再进行相应的操作,通过反射我们可以得到这个对象的所有信息,所以想要进行什么操作也是可以的。

这就是注解从定义到起作用的一个过程,举个第三步的例子:
当我们给一个方法加上了一个注解

public class TestAnnotation {
    public static void main(String[] args) {

        XXX类 对象= new XXX();

        Class clazz = 对象.getClass();

        Method[] method = clazz.getDeclaredMethods();

        for ( Method m: method ) {
            if ( m.isAnnotationPresent( annotation.class )) {
               如果方法有此注解,我们就可以进行想要进行的操作
               ...........
        }
    }
}

至此我们对注解的实现应该有了一个初步的了解了,以下是注解的其他基本概念。

注解基本概念

元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解。Java 5 定义了 4 个注解,分别是 @documented、@Target、@Retention 和 @Inherited。Java 8 又增加了 @Repeatable 和 @Native 两个注解。

@documented

@documented 是一个标记注解,没有成员变量。用 @documented 注解修饰的注解类会被 Javadoc 工具提取成文档。默认情况下,Javadoc 是不包括注解的,但如果声明注解时指定了 @documented,就会被 Javadoc 之类的工具处理,所以注解类型信息就会被包括在生成的帮助文档中。

@Target

@Target 注解用来指定一个注解的使用范围,即被 @Target 修饰的注解可以用在什么地方。@Target 注解有一个成员变量(value)用来设置适用目标,value 是 java.lang.annotation.ElementType 枚举类型的数组,下表为 ElementType 常用的枚举常量。

ElementType.ANNOTATION_TYPE 可以给一个注解进行注解ElementType.ConSTRUCTOR 可以给构造方法进行注解ElementType.FIELD 可以给属性进行注解ElementType.LOCAL_VARIABLE 可以给局部变量进行注解ElementType.METHOD 可以给方法进行注解ElementType.PACKAGE 可以给一个包进行注解ElementType.PARAMETER 可以给一个方法内的参数进行注解ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举 @Retention

@Retention 用于描述注解的生命周期,也就是该注解被保留的时间长短。@Retention 注解中的成员变量(value)用来设置保留策略,value 是 java.lang.annotation.RetentionPolicy 枚举类型,RetentionPolicy 有 3 个枚举常量,如下所示。保留时长后面的包含前面的。

    SOURCE:在源文件中有效(即源文件保留)CLASS:在 class 文件中有效(即 class 保留)RUNTIME:在运行时有效(即运行时保留)
@Inherited

@Inherited 是一个标记注解,用来指定该注解可以被继承。使用 @Inherited 注解的 Class 类,表示这个注解可以被用于该 Class 类的子类。就是说如果某个类使用了被 @Inherited 修饰的注解,则其子类将自动具有该注解。

@Repeatable

@Repeatable 注解是 Java 8 新增加的,它允许在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助 @Repeatable 注解。Java 8 版本以前,同一个程序元素前最多只能有一个相同类型的注解,如果需要在同一个元素前使用多个相同类型的注解,则必须使用注解“容器”。重复使用赋予不同的值,相当于全都放到集合之中。

@Native

使用 @Native 注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。

由于才疏学浅,难免有错漏之处,还望不吝赐教。
本文地址转载请注明:https://blog.csdn.net/elapse_/article/details/122645746

Reference

Java元注解作用及使用:http://c.biancheng.net/view/7009.html
秒懂,Java 注解 (Annotation)你可以这样学:https://zhuanlan.zhihu.com/p/27643133

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/716728.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号