注解 笔记

1 注解

注解到底是干什么的?_张铎-CSDN博客

注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记。标记可以加在包、类,属性、方法,方法的参数以及局部变量上。

第一阶段最早在继承父类然后方法重载的时候就接触过注解。

@override就是一个标识,说明这是一个重写的方法。实际编译为字节码文件时就没有用了,只是在源码进行标识和判断方法重载的格式是否正确。

有一些注解则具备功能性

比如@getting 和@webServlet(将servlet配置到web.xml中,即映射到tomcat根目录)

1.1 创建注解

注解就是接口,在创建的时候设置为接口即可,注解要单独放在一个包里,包名annotation 中文翻译即注解

此时的接口还只是一个普通接口,需要在interface前加上@符号 才能转为注解类

此时这个注解就可以被使用了,但是此时的注解仅仅具备标识作用,可以被写在类上或者构造方法上,一个对象上可以被施加多个注解

1.2 注解的属性

注解可以设置属性,注意以下几点:

数据类型 属性名() default 值

  1. 设置数据类型与设置类时一致,但要注意设置基本数据类型时要给原始类型,不能给包裹类型
  2. 属性名后要加小括号
  3. default用于设置默认值
  4. 设置多个值,比如设置为数组时,要用大括号表示数组{},数组内各个元素用逗号隔开

实例:

设置注解属性

使用注解并给注解传值,传多个值时要用逗号隔开,并且写成k-v的格式

1.3 元注解

所谓元注解就是声明在注解上的注解,元注解是注解的一种声明,用于设置注解。

JDK1.5开始提供注解,给了4个注解,常用的是其中两个注解

@Retention

保留期,声明注解的存活时间

@Documented

保留本类中的注解并能够被javadoc识别

@Target

指定注解的运行地方(类/方法/变量等)

@Inherited

注解是否可以被子类继承

1.3.1 @Retention

Retention的意思是保留期(或者叫存活期)的意思,是指定该注解在JVM中的存活期的注解

存活期:源码阶段(.java文件)   编译阶段(.class)    运行阶段

不设置存活期时,默认存活期到编译阶段

RetentionPolicy.SOURCE

注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视

RetentionPolicy.CLASS

注解只被保留到编译进行的时候,它并不会被加载到JVM 中,默认时@Retention就设置为这个值

RetentionPolicy.RUNTIME

注解可以保留到程序运行的时候,它会被加载进入到JVM 中,如果希望能在代码运行时取到注解的值,必须设置为这个值

源码说明:

这个注解只有一个属性,用于设置注解的保留期,该注解用枚举保存了三个值,根据传入的值确定设置的保留期

实际执行时,JAVA文件会被编译为字节码文件,此时代码从上至下执行,遇到注解时就会进入,然后读取@Retention以确定当前注解的保存期,再决定是否将这个注解保存在字节码中

代码:

使用:

1.3.2 @Target

指定当前声明的注解可运行的范围的标记,通过该注解可以指定声明的注解具体运行在类/方法/变量上等

ElementType.ANNOTATION_TYPE

可以给一个注解进行注解

ElementType.CONSTRUCTOR

可以给构造方法进行注解

ElementType.FIELD

可以给属性进行注解

ElementType.LOCAL_VARIABLE

可以给局部变量进行注解

ElementType.METHOD

可以给方法进行注解

ElementType.PACKAGE

可以给一个包进行注解

ElementType.PARAMETER

可以给一个方法内的参数进行注解

ElementType.TYPE

可以给一个类型进行注解,比如类、接口、枚举

源码说明:

这个注解只有一个属性,用于设置的注解的可运行地点,该注解用枚举保存了十个值,根据传入的值确定注解能作用的地方

代码:

使用:

设置注解允许放的位置,可以只设置一个,也可以设置多个,设置多个时用大括号括起来,值之间用逗号隔开

此时如果注解放的地方不对,就会报错,如图放在构造方法上就报错了

 

 

1.4 获取类上的注解

JAVA提供了封装好的反射方法,基于Class对象,能获取到加在类上的注解

Class对象 . getAnnotation(注解名.class)

返回类中指定名字的注解,此时得到的是一个注解对象 Annotation

Class对象 . getAnnotation()

返回类中所有注解,此时得到的是一个注解数组 Annotation[]

注解名 变量名 = (注解名) Annotation对象

通过上面的方法获得的Annotation对象需要强制转换为具体的注解,才能获取详细的属性

Annotation对象 . annotationType()

获取到注解对象的全类名

注意:

 getAnnotation()返回的是父接口类型的对象,就比如取一个对象,返回的是一个object对象,如果希望获取到对象中的具体的属性,必须向下造型。

方法:

实例 获取指定的注解:

①某个类设置的注解如图,一个类上可以设置多个注解,类中的方法或者变量也可以单独设置注解

②在test测试类中创建一个指向类的Class对象,再调用方法获取到类中指定名字的注解

③获取到注解对象后,可以进一步取值,注意必须使用强制转换

实例 获取多个注解:

获取到类中所有注解后,循环输出

1.5 获取类的构造器上的注解

如果需要获取加在类的构造器上的注解,不能通过类获取,得通过类的构造器

Constructor 变量名 = Class对象 . getConstructor()

获取无参构造器

Constructor 变量名 = Class对象 . getConstructor(String.class, String.class)

通过参数类型获取有参的构造器,显然这得先知道想要的构造器的具体参数表

Constructor对象 . getAnnotation(注解名.class)

返回类的构造器上指定名字的注解,此时得到的是一个注解对象 Annotation

Constructor对象 . getAnnotation()

返回类的构造器上所有注解,此时得到的是一个注解数组 Annotation[]

注解名 变量名 = (注解名) Annotation对象

通过上面的方法获得的Annotation对象需要强制转换为具体的注解,才能获取详细的属性

注意:

 getAnnotation()返回的是父接口类型的对象,就比如取一个对象,返回的是一个object对象,如果希望获取到对象中的具体的属性,必须向下造型。

实例:

Clazz指向的类的构造器:

对应的注解属性:

代码与结果:

①获取到的注解只是类的构造器上的值。

②注解的属性值被定义时就会修改,未被定义时就保持默认值

1.6 获取类的属性上的注解

如果需要取到类的属性上的注解,需要先获取到类的属性

Field 变量名 = Class对象 . getField( "变量名" )

获取类中指定名字的公开的成员变量,返回一个对象

Field[] 变量名 = Class对象 . getFields()

获取类中所有公开的成员变量,包括从父类继承的公开的成员变量,返回一个对象数组

Field 变量名 = Class对象 . getDeclaredField( "变量名" );

获取类中指定名字的成员变量,即便这个变量是否公开,返回一个对象

Field[] 变量名 = Class对象 . getDeclaredFields();

获取类中所有的成员变量,但不包括从父类继承的成员变量,返回一个对象数组

Field对象 . getAnnotation(注解名.class)

返回类的构造器上指定名字的注解,此时得到的是一个注解对象 Annotation

Field对象 . getAnnotation()

返回类的构造器上所有注解,此时得到的是一个注解数组 Annotation[]

注意:

通过类的属性获取到属性上的注解,直接就是注解对象,而不是父接口对象Annotation,不需要强制类型转换

实例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值