java 元数据 注解_Java:注解Annotation(元数据)

本文内容:

注解Annotation的介绍

基本注解的用法

自定义注解

首发日期:2018-07-28

注解Annotation的介绍

Annotation是代码中的特殊标记,能够在编译、类加载、运行时被识别(需要设置),并根据不同的Annotation来执行不同的处理。

Annotation可以修饰包、类、构造器、函数、成员变量、局部变量的声明、参数等程序元素。Annotation帮助这些元素来设置元数据,程序从元数据中获取信息来处理这些元素。

元数据可以描述代码间关系或者代码与其它资源的关系,比如说在web.xml中需要将请求路径跟处理请求的servlet对应起来,比如说在Hibernate中需要.hbm文件来描述实体类与数据表之间的映射关系。元数据可以提供某些信息来协助我们程序的运行。

在Java中,Annotation就可以帮我们在代码层面上去设置元数据,而不必需要去使用一些例如web.xml的文件来描述。

基本注解的用法

如何使用注解修饰元素:

通常来说,在修饰目标的上一行进行注解,比如9386e9f49b99b49d858c4d965ceb78a6.png。修饰成员变量也是如此。

常用的基本的Annotation:

@Override :指明下面修饰的函数必须是重写父类的函数的函数,如果修饰的函数不在父类中存在,那么会报错。

@Deprecated :标明函数、类等元素已过时,效果是在使用已经过时的元素时会警告。

@SuppressWarnings:抑制修饰的元素发生警告(warning),效果是修饰过后,编译器不会提示警告。

@SafeVarargs【Java7新增】:如果把一个没有定义泛型的集合,赋给一个有定义泛型的集合,会发生堆污染,会报错。@SafeVarargs可以抑制这个报错。

@FunctionalInterface【Java8新增】:用来限制修饰的接口必须是一个函数式接口,不然会报错。

元Annotaion:修饰注解的注解

@Retention:指定Annotation的保留方式,保留方式不同,会影响能被使用的位置。比如如果需要通过反射获取信息,那么应该允许运行时还能获取。

@Retention(RetentionPolicy.CLASS):默认值,代表把注解留在class文件中,程序运行后,JVM将无法获取注解。【由于里面的成员变量名为value,所以可以省去 参数名="xxx",如果不是value,那么不可以省去!】

@Retention(RetentionPolicy.RUNTIME):代表把注解留在class文件中,程序运行后,JVM可以通过反射来获取注解。

@Retention(RetentionPolicy.SOURCE):只留在源代码中,JVM不会获取到注解。

@Target:限制Annotaion能修饰哪些元素

@Target(ElemenetType.ANNOTATION_TYPE):指定被修饰的Annotaion只能用来修饰Annotaion

@Target(ElemenetType.FIELD):指定被修饰的Annotaion只能用来修饰成员变量

@Target(ElemenetType.CONSTRUCTOR):指定被修饰的Annotaion只能用来修饰构造器

@Target(ElemenetType.METHOD):指定被修饰的Annotaion只能用来修饰函数

@Target(ElemenetType.LOCAL_VARIABLE):指定被修饰的Annotaion只能用来修饰局部变量

@Target(ElemenetType.PACKAGE):指定被修饰的Annotaion只能用来修饰包

@Target(ElemenetType.PARAMETER):指定被修饰的Annotaion只能用来修饰参数

@Target(ElemenetType.TYPE):指定被修饰的Annotaion只能用来修饰类、接口(包括注解类型)或枚举定义

@Documented:指定Annotaion是否能包含到javadoc生成的文档中。

@Inherited:指定Annotaion具有继承性,父类定义了这个注解,那么子类也会继承这个注解。

自定义注解

自定义注解跟定义接口差不多,在interface的基础上加一个@

dfd168b4f7eeee2e0e60bc64708101da.png

当就是这么空,不写东西的时候,是一个标记型的注解,标记型的注解功能比较简单,通常只能用来标记特殊的元素从而进行处理。比如Override就是一个标记型的注解。

注解可以定义成员变量,这些成员变量以声明无形参函数的形式存在,返回值是变量的类型,函数名是变量的名字。注解上定义的成员变量只能是String、数组、Class、枚举类、注解。成员变量可以提供更多的元数据信息。

d6c6af4ac14dfad624cb61d1c20e4966.png

定义了成员变量后,在使用的时候需要给成员变量赋值(成员变量名为value时,可以省去value="xxx",但是这个名字时,不可以省略)。在没有成员变量时,可以单写注解名,要赋值时就要用上括号。

1c972bbe8923b4efdac093bba937bd54.png

如果某些成员变量不需要每次都赋值,可以给它设置默认值。成员变量可以有默认值,在变量的后面加上default 默认值.

9673dca8fd767566f0864895ebc6ce00.png

注解处理器:

对于Java自带的注解,Java有自己的注解处理器去处理。但自定义的注解,需要自己去定义注解处理器,自己去调用注解处理器去处理。所以,注解处理器本质上也是一个普通函数,不过它的工作主要是处理注解罢了。

在学会怎么定义注解处理器之前先了解几个前置知识:

所有注解的父接口都是Annotation。

一个注解,只有它的存在时间足够我们才能使用它,所以如果我们想使用注解处理器,注解首先需要使用@Retention(RetentionPolicy.RUNTIME)修饰。

java.lang.reflect包中存在一些能够实现反射功能的工具类。

java.lang.reflect包中有一个AnnotationElement接口,它声明了一系列可以获取注解的函数,并且它有几个实现类,如下所见,所以你可以在类、构造函数等对象中调用声明好的函数来获取注解。a71dc5d60eaa1c0f1a8ef39aaa98f588.png

getAnnotation(注解.class):获取对应类型的注解

getAnnotations():获取所有注解

getDeclaredAnnotations():获取直接注解,忽略继承过来的注解。

isAnnotationPresent(注解.class):判断对应类型的注解是否存在

获取注解:

dc41ab6a3992d8fb513ae0adb112d448.png

6e9aba108568db4ecac1411293e82c41.png

....其他对象就演示了。

操作注解:通常来说,都是处理注解带上的信息。

205d7a4e0ba1011da59649a00a79c6a2.png

小例子

不知道你有没有了解过org.junit.Test这个东西,这个可以让你直接运行你想要运行的函数(可以称为单元测试?)。而不需要你创建一个main()去调用。

下面做一个示例,来实现类似的功能:

1.创建注解:

837d0297be25d7c2ea1a6e01fdc9c0e7.png

2.使用注解:

7ea92e36ec3cd66c79d9f9c0e4858cad.png

3.调用注解处理器:【这里使用了org.junit.Test来调用,你也可以在main()中调用!】

a3525bdb6aabe0e334ad4a7ef7581708.png

结果是:

e167b5dc2958faf4e863d03d6a05413e.png

补充:

上面的小例子中并没有使用注解的成员变量,但事实上,使用成员变量也同样只是获取里面的信息来做更多处理罢了,这就依靠个人去应用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值