一、概念
注解(Annotation)是在 Java 1.5 同时引入的概念 class 和 interface 同样,它也属于一种类型。注释为装饰程序代码(类别、方法、字段等)提供了一系列数据,但注释不是装饰代码的一部分,对代码的运行效果没有直接影响,编译器决定执行哪些操作。
二、生命周期的注释SOURCE注释有三个生命周期、CLASS、RUNTIME,RetentionPolicy定义 枚举中。
SOURCE:编译器丢弃了源文件。
CLASS:它在编译器生成的字节码文件中有效,但在运行过程中会被处理 JVM 丢弃。
RUNTIME:操作有效。这也是注释生命周期中最常用的策略。它允许程序通过反射访问注释,并根据注释的定义执行相应的代码。
三、注释目标注释的目标定义将适用于哪种类型的注释 Java 代码,截止日期 Java 9.注释的类型总共有 11 种,定义在 ElementType 枚举中。
TYPE:用于类、界面、注释、枚举
FIELD:用于字段(类成员变量)或枚举变量
METHOD:参数用于普通方法或结构方法
CONSTRUCTOR:用于结构方法
LOCAL_VARIABLE:用于变量
ANNOTATION_TYPE:用于注解
PACKAGE:用于包
TYPE_PARAMETER:用于泛型参数
TYPE_USE:用于声明句子、泛型或强制转换句子中的类型
MODULE:用于模块
四、测试1.自定义Json数据过滤注释
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @author qinxun * @date 2023-06-12 * @Descripion: 自定义json忽略了注释 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface JsonIgnore {}
2.创建要操作的实体类
/** * @author qinxun * @date 2023-06-12 * @Descripion: 学生测试类 */public class Student { private String name; /** * 在标记json数据返回时,忽略了该字段 */ @JsonIgnore private int age; private String address; public Student() { } public Student(String name, int age, String address) { this.name = name; this.age = age; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", address='" + address + '\'' + '}'; }}
3.自定义Json序列化类型
import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;import java.util.stream.Collectors;/** * @author qinxun * @date 2023-06-12 * @Descripion: Json序列化类 */public class JsonSerializer { /** * 自定义序列化对象 * * @param object 对象要序列化 */ public static String serialize(Object object) throws IllegalAccessException { Class<?> objectClass = object.getClass(); Map<String, String> jsonMap = new HashMap<>(); // 通过反射获得对象声明的所有字段 for (Field field : objectClass.getDeclaredFields()) { field.setAccessible(true); // 判断成员变量是否使用@Jsonignore注释 if (!field.isAnnotationPresent(JsonIgnore.class)) { jsonMap.put(field.getName(), (String) field.get(object)); } } return toJsonString(jsonMap); } /** * 格式化字符串 * * @param jsonMap 字符串Map集合 * @return 格式化后的字符串 */ private static String toJsonString(Map<String, String> jsonMap) { String elementStr = jsonMap.entrySet().stream().map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"") .collect(Collectors.joining(",")); return "{" + elementStr + "}"; }}
4.创建测试测试
/** * @author qinxun * @date 2023-06-12 * @Descripion: 自定义注释测试 */public class JsonIgnoreTest { public static void main(String[] args) throws IllegalAccessException { Student student = new Student("qq", 28, "广州"); // 输出{"address":"广州","name":"qq"} System.out.println(JsonSerializer.serialize(student)); }}
我们发现,使用@Jsonignore注解的字段没有显示在返回Json数据中,实现了字段的过滤。