Java 自定义注解及使用
我们定义一个类的时候是使用的 class 关键字定义的,现在我们想定义一个自己的注解 需要使用 @interface 关键字来定义。@Retention 用来指定注解的生命周期(源码、class文件、运行时),其可选值如下:●RetentionPolicy**.SOURCE** : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @Suppre
目录
一、自定义注解
1.使用 @interface 来定义你的注解
我们定义一个类的时候是使用的 class 关键字定义的,现在我们想定义一个自己的注解 需要使用 @interface 关键字来定义。
如定义一个叫 MyAnnotation 的注解:
public @interface MyAnnotation { }
2.使用 @Retention 注解来声明自定义注解的生命周期
@Retention 用来指定注解的生命周期(源码、class文件、运行时),其可选值如下:
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。
声明 MyAnnotation 注解的生命周期是 RetentionPolicy.RUNTIME:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
3.使用 @Target 注解来声明注解的使用范围
@Target 用来声明注解可以用在哪些地方(类上、类成员变量上、方法上、参数上等),其可选值如下:
● ElementType.CONSTRUCTOR :用于描述构造器。
● ElementType.FIELD :成员变量、对象、属性(包括enum实例)。
● ElementType.LOCAL_VARIABLE: 用于描述局部变量。
● ElementType.METHOD : 用于描述方法。
● ElementType.PACKAGE :用于描述包。
● ElementType.PARAMETER:用于描述参数。
● ElementType.ANNOTATION_TYPE:用于描述参数
● ElementType.TYPE :用于描述类、接口(包括注解类型) 或enum声明。
声明 MyAnnotation 注解可用于类成员变量和方法上:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyAnnotation {
}
4.添加注解的属性
为 MyAnnotation 注解添加 id 和 describe 属性:
package com.hai.tang.annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyAnnotation {
int id();
String describe();
}
也可以为 id 和 describe 属性添加默认值,当 id 或 describe 属性不指定具体的值的时候就会使用默认值:
package com.hai.tang.annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyAnnotation {
int id() default 0;
String describe() default "";
}
到这里你已经完整定义了一个叫 MyAnnotation 的注解,其声明周期是运行时,可注解在类成员变量和方法上,拥有 id 和describe 两个属性并拥有默认值。
二、使用自定义的注解
1.将注解注在其允许的使用范围
上面 MyAnnotation 注解,可注解在类成员变量和方法上。
package com.hai.tang.model;
import com.alibaba.fastjson2.annotation.JSONField;
import com.hai.tang.annotation.MyAnnotation;
public class Student {
@JSONField(ordinal =0)
@MyAnnotation
public String name;
@MyAnnotation(id=1,describe="分数")
public Integer score;
public Student() {
}
@MyAnnotation(describe="getName方法")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
2.使用反射获取类成员变量上的所有注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class MainServer {
public static void main(String[] args) {
Class<?> studentClass = Student.class;
Field[] fields = studentClass.getDeclaredFields();//获取所有的类成员变量字段
for (Field field : fields) {
String fieldName = field.getName(); //获取该类成员变量的名字
System.out.println("成员变量名是:" + fieldName);
Annotation[] annotations = field.getAnnotations(); //获取该类成员变量上所有声明周期是运行时的注解
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();
String annotationName = annotationType.getSimpleName();//注解的简短名称
System.out.println(" 使用的注解是:" + annotationName);
//判断该注解是不是 MyAnnotation 注解,是的话打印其 id 和 describe 属性
if (annotationType.equals(MyAnnotation.class)) {
MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);
int id = myAnnotation.id();
String describe = myAnnotation.describe();
System.out.println(" MyAnnotation注解中的id是:" + id);
System.out.println(" MyAnnotation注解中的describe是:" + describe);
}
}
System.out.println();
}
}
}
输出:
成员变量是:name
使用的注解是:JSONField
使用的注解是:MyAnnotation
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:
成员变量是:score
使用的注解是:MyAnnotation
MyAnnotation注解中的id是:1
MyAnnotation注解中的describe是:分数
3.反射获取成员变量上的指定注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Field;
public class MainServer {
public static void main(String[] args) {
Class<?> studentClass = Student.class;
//反射遍历所有成员变量
Field[] fields = studentClass.getDeclaredFields();
for (Field field : fields) {
//如果其成员变量上有 MyAnnotation 注解,就打印成员变量名和注解里的内容
if (field.isAnnotationPresent(MyAnnotation.class)) {
String fieldName = field.getName();
//获取变量字段上的 MyAnnotation 注解
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
int id = annotation.id();
String describe = annotation.describe();
System.out.println("成员变量是:" + fieldName);
System.out.println("MyAnnotation注解中的id是:" + id);
System.out.println("MyAnnotation注解中的describe是:" + describe);
}
System.out.println();
}
}
}
输出:
成员变量是:name
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:
成员变量是:score
MyAnnotation注解中的id是:1
MyAnnotation注解中的describe是:分数
4.获取方法上的指定注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Method;
public class MainServer {
public static void main(String[] args) {
Class<?> studentClass = Student.class;
//反射遍历所有方法
Method[] methods = studentClass.getDeclaredMethods();
for (Method method : methods) {
//如果其方法上有 MyAnnotation 注解,就打印方法名和注解里的内容
if (method.isAnnotationPresent(MyAnnotation.class)) {
String methodName = method.getName();
//获取方法上的 MyAnnotation 注解
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
int id = annotation.id();
String describe = annotation.describe();
System.out.println("方法名是:" + methodName);
System.out.println("MyAnnotation注解中的id是:" + id);
System.out.println("MyAnnotation注解中的describe是:" + describe);
}
}
}
}
输出:
方法名是:getName
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:getName方法
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)