本文和大家聊聊Java注解
什么是注解?
咱们先来看看Java官方定义:
注解是一种元数据形式,提供程序本身以外的数据,对代码没有直接的影响。
这是说的啥?相信很多朋友初次看到注解定义都会有这样的反应。
那有没有一种通俗易懂的定义或是比喻呢?
我觉得可以把注解比喻成电子标签,因为电子标签可以为粘贴它的物品,提供解释与说明,这和注解的作用很相似。
如何声明一个注解?
下面咱们来声明一个注解,代码如下:
public @interface TestAnnotation {
int id();
Srting value() default "N/A"
}
咱们来分析一下上面的代码:
- @interface:注解关键字
- TestAnnotation:注解名
- id、value:注解的参数
哪些类型可以作为注解的参数?
注解的参数可支持数据类型:
- 所有基本数据类型(int,float,double,boolean,byte,char,long,short)
- String 类型
- Class类型
- 以上所有类型的数组
在讲解如何使用注解之前,咱们先来看看什么是元注解?这对后面更好的理解注解很有助益
什么是元注解?
官方的定义:用于解释注解的注解
咱们前面把注解比喻成电子标签,
这里可以把元注解看作电子标签的说明书,因为说明书会描述电子标签的用途和使用范围,这个元注解的作用很相似。
下面举个使用元注解的例子:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id();
Srting value() default ''N/A''
}
元注解有哪些?
下面咱们看看有哪些元注解,以及它的作用
@Retention指定注解的保留方式:
RetentionPolicy.SOURCE - 标识的注解仅保留在源代码级别,并被编译器忽略。
RetentionPolicy.CLASS - 标识的注解在编译时由编译器保留,但被Java虚拟机(JVM)忽略。
RetentionPolicy.RUNTIME - 标识的注解由JVM保留,以便运行时环境使用它。@Documented 在任何时使用指定的注解,这些元素都应该使用Javadoc工具进行记录。(默认情况下,Javadoc中不包含注释)
@Target 用来限制注解的用途。其值:
ElementType.ANNOTATION_TYPE 可以应用于注释类型。
ElementType.CONSTRUCTOR 可以应用于构造函数。
ElementType.FIELD 可以应用于一个属性。
ElementType.LOCAL_VARIABLE 可以应用于局部变量。
ElementType.METHOD 可以应用于方法级别的注释。
ElementType.PACKAGE 可以应用于包声明。
ElementType.PARAMETER 可以应用于方法的参数。
ElementType.TYPE 可以应用于任何类的元素。@Inherited 表示注解类型可以从超类继承。当子类没有这个类型的注解时,查询该类的超父类的注解类型。这个注解只适用于类声明。
@Repeatable 表示注解可以多次应用于相同的声明或类型。(Java 8新加入的)
注解的用途
注释有许多用途,其中包括:
- 编译器信息: 编译器可以使用注解来检测错误或取消警告。
- 编译时和部署时处理: 软件工具可以处理注解信息以生成代码,XML文件等。
- 运行时处理: 可在运行时检查。
- 开发框架:ButterKnife、Retrofit、Dagger、Google的Room
注解的使用
下面咱们通过一个例子,来看看该如何使用注解。
获取注解信息用到了Java反射相关的内容,如有需要,请移步Java反射基础与实践
本例展示在代码中如何使用注解。
第一步,声明一个注解。代码如下:
package com.hys;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimpleAnnotation {
int id();
String description();
}
第二步,在类中使用它,还记得上文中咱们对注解的比喻吗?这一步相当于给类的方法贴一个电子标签。代码如下:
package com.hys;
public class User {
private String mName;
private int mAge;
@SimpleAnnotation(id=1, description="Get user name")
public String getName(){
return mName;
}
@SimpleAnnotation(id=2, description="Get User age")
public int getAge(){
return mAge;
}
}
第三步,在程序运行时,读取注解所提供的方面描述信息。代码如下:
package com.hys;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) {
try {
Class userClazz = Class.forName("com.hys.User");
Method[] methods = userClazz.getDeclaredMethods();
for(Method method : methods){
if(!method.isAnnotationPresent(SimpleAnnotation.class))
continue;
SimpleAnnotation annotation = method.getAnnotation(SimpleAnnotation.class);
System.out.println("Method name:" + method.getName());
System.out.println("Method id:" + annotation.id());
System.out.println("Method description:" + annotation.description());
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
执行结果:
Method name:getName
Method id:1
Method description:Get user name
Method name:getAge
Method id:2
Method description:Get User age
总结, 注解是为它依附的对象(类、方法、属性、方法的参数、局部变量、包)提供解释与说明;元注解是说明注解的用途和使用范围。
我是青岚之峰,如果读完后有所收获,欢迎点赞加关注!