如何通过一张图和案例快速学会Java自定义注解?

2026-05-17 01:571阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2169个文字,预计阅读时间需要9分钟。

如何通过一张图和案例快速学会Java自定义注解?

1. 概述是什么:概述是对方法、类、参数、包、域以及变量等进行代码功能增强或修改的行为。这包括追踪代码依赖性、实现替代配置文件功能、在反射中使用Annotation等操作。

应用:- 追踪代码依赖性- 实现替代配置文件功能- 在反射中使用Annotation- 字段

1.概述

是什么:是对方法、类、参数、包、域以及变量等进行代码功能的增强或者修改程序的行为等操作。

应用

  • 跟踪代码依赖性,实现替代配置文件功能
  • 在反射中使用Annotation,字段格式化(如:数据字段脱敏、日期格式)
  • 在编译时进行格式检查
  • 生成帮助文档
2.注解相关知识

元注解指的是所有注解都基于它们而产生的最基础的注解。

2.1.Annotation接口和元注解

这张图包含了Annotation接口信息、4个元注解作用和元注解的参数信息

整体关系(具体信息都在图中)

  • 顶级注解接口:Annotation

  • 元注解

    • @Documented
    • @Inherited
    • @Target
    • @Retention
  • native级别的关键字

    • @interface 指明是注解类

关联关系

  • 1个Annotation 和 1个RetentionPolicy关联。

    • 可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。
  • 1个Annotation 和 1~n个ElementType关联。

    • 可以理解为:对于每1个Annotation对象,可以有若干个ElementType属性。
2.2.注解元素支持的数据类型
  • 所有基本类型
  • String
  • Class
  • enum
  • annotation
  • 以上类型的数组
2.3.常见基础注解的作用

@SuppressWarnings:抑制编译器警告的注解,编译检查注解

@Deprecated:弃用注解,编译检查注解

@Override:限定重写父类方法的注解,具有编译检查作用

@FunctionalInterface:函数式接口注解,限制接口只能有一个抽象方法

3.自定义注解

返回值类型等于参数的类型,

方法的名称等于参数的名称(使用注解是参数名称),

可以通过default关键字来声明参数的默认值。

通过一个案例来理解注解的使用(不懂反射的可以看我的另一篇文章)

3.1.案例:通过反射处理自定义注解

自定义注解类:颜色注解类 + 颜色枚举

@Target( ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ColorBanana { /** * 颜色枚举类 */ public enum Color{ YELLOW, BLACK, WHITE, RED } // 颜色属性 Color colorBanana() default Color.YELLOW; }

实体类:使用注解的类

public class Banana { private String bananaName; @ColorBanana(colorBanana = ColorBanana.Color.RED) private String bananaColor; public String getBananaName() { return bananaName; } public void setBananaName(String bananaName) { this.bananaName = bananaName; } public String getBananaColor() { return bananaColor; } public void setBananaColor(String bananaColor) { this.bananaColor = bananaColor; } @Override public String toString() { return "Banana{" + "bananaName=" + bananaName + ", bananaColor=" + bananaColor + "}"; } }

测试类:反射处理注解

public class BananaTest { // 创建注解赋值后的Banana实例对象 public static Banana newBanana() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<Banana> bananaClass = Banana.class; Banana banana = bananaClass.getConstructor().newInstance(); /** * 获取Banana类中 ColorBanana注解信息 * 因为注解信息打在成员变量上,所以要通过Filed来get注解 * (注解打在什么上,就用什么来获取注解) */ Field[] fields = bananaClass.getDeclaredFields();//注解打在私有成员变量,所以要用getDeclaredFields for (Field field : fields){ field.setAccessible(true);//忽略私有修饰符得限制,否则报语法错误 // 拿到注解 ColorBanana annotation = field.getAnnotation(ColorBanana.class); // 有些字段没有ColorBanana注解,记得判空 if (annotation != null){ ColorBanana.Color color = annotation.colorBanana(); System.out.println("输出注解中得信息:"+field.getName()+"="+color); /* * 将注解中得信息赋值到对象对应字段中 * 因为实体类Banana 的bananaColor字段是字符串,所以要拿枚举类属性得name(名称)进行赋值 */ field.set(banana,color.name()); } } // 输出反射得到得对象信息 System.out.println(banana); return banana; } public static void main(String[] args) throws Exception { Banana banana = newBanana(); banana.setBananaName("myBananaName"); System.out.println(banana); } }

执行结果:

输出注解中得信息:bananaColor=RED

Banana{bananaName=null, bananaColor=RED}

Banana{bananaName=myBananaName, bananaColor=RED}

注解值成功传入到实例化对象中的对应字段,并返回实例化对象给调用者。

Java往期文章

Java全栈学习路线、学习资源和面试题一条龙

如何通过一张图和案例快速学会Java自定义注解?

我心里优秀架构师是怎样的?

免费下载经典编程书籍

原创不易,三联支持:点赞、在看、分享

本文共计2169个文字,预计阅读时间需要9分钟。

如何通过一张图和案例快速学会Java自定义注解?

1. 概述是什么:概述是对方法、类、参数、包、域以及变量等进行代码功能增强或修改的行为。这包括追踪代码依赖性、实现替代配置文件功能、在反射中使用Annotation等操作。

应用:- 追踪代码依赖性- 实现替代配置文件功能- 在反射中使用Annotation- 字段

1.概述

是什么:是对方法、类、参数、包、域以及变量等进行代码功能的增强或者修改程序的行为等操作。

应用

  • 跟踪代码依赖性,实现替代配置文件功能
  • 在反射中使用Annotation,字段格式化(如:数据字段脱敏、日期格式)
  • 在编译时进行格式检查
  • 生成帮助文档
2.注解相关知识

元注解指的是所有注解都基于它们而产生的最基础的注解。

2.1.Annotation接口和元注解

这张图包含了Annotation接口信息、4个元注解作用和元注解的参数信息

整体关系(具体信息都在图中)

  • 顶级注解接口:Annotation

  • 元注解

    • @Documented
    • @Inherited
    • @Target
    • @Retention
  • native级别的关键字

    • @interface 指明是注解类

关联关系

  • 1个Annotation 和 1个RetentionPolicy关联。

    • 可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。
  • 1个Annotation 和 1~n个ElementType关联。

    • 可以理解为:对于每1个Annotation对象,可以有若干个ElementType属性。
2.2.注解元素支持的数据类型
  • 所有基本类型
  • String
  • Class
  • enum
  • annotation
  • 以上类型的数组
2.3.常见基础注解的作用

@SuppressWarnings:抑制编译器警告的注解,编译检查注解

@Deprecated:弃用注解,编译检查注解

@Override:限定重写父类方法的注解,具有编译检查作用

@FunctionalInterface:函数式接口注解,限制接口只能有一个抽象方法

3.自定义注解

返回值类型等于参数的类型,

方法的名称等于参数的名称(使用注解是参数名称),

可以通过default关键字来声明参数的默认值。

通过一个案例来理解注解的使用(不懂反射的可以看我的另一篇文章)

3.1.案例:通过反射处理自定义注解

自定义注解类:颜色注解类 + 颜色枚举

@Target( ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ColorBanana { /** * 颜色枚举类 */ public enum Color{ YELLOW, BLACK, WHITE, RED } // 颜色属性 Color colorBanana() default Color.YELLOW; }

实体类:使用注解的类

public class Banana { private String bananaName; @ColorBanana(colorBanana = ColorBanana.Color.RED) private String bananaColor; public String getBananaName() { return bananaName; } public void setBananaName(String bananaName) { this.bananaName = bananaName; } public String getBananaColor() { return bananaColor; } public void setBananaColor(String bananaColor) { this.bananaColor = bananaColor; } @Override public String toString() { return "Banana{" + "bananaName=" + bananaName + ", bananaColor=" + bananaColor + "}"; } }

测试类:反射处理注解

public class BananaTest { // 创建注解赋值后的Banana实例对象 public static Banana newBanana() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<Banana> bananaClass = Banana.class; Banana banana = bananaClass.getConstructor().newInstance(); /** * 获取Banana类中 ColorBanana注解信息 * 因为注解信息打在成员变量上,所以要通过Filed来get注解 * (注解打在什么上,就用什么来获取注解) */ Field[] fields = bananaClass.getDeclaredFields();//注解打在私有成员变量,所以要用getDeclaredFields for (Field field : fields){ field.setAccessible(true);//忽略私有修饰符得限制,否则报语法错误 // 拿到注解 ColorBanana annotation = field.getAnnotation(ColorBanana.class); // 有些字段没有ColorBanana注解,记得判空 if (annotation != null){ ColorBanana.Color color = annotation.colorBanana(); System.out.println("输出注解中得信息:"+field.getName()+"="+color); /* * 将注解中得信息赋值到对象对应字段中 * 因为实体类Banana 的bananaColor字段是字符串,所以要拿枚举类属性得name(名称)进行赋值 */ field.set(banana,color.name()); } } // 输出反射得到得对象信息 System.out.println(banana); return banana; } public static void main(String[] args) throws Exception { Banana banana = newBanana(); banana.setBananaName("myBananaName"); System.out.println(banana); } }

执行结果:

输出注解中得信息:bananaColor=RED

Banana{bananaName=null, bananaColor=RED}

Banana{bananaName=myBananaName, bananaColor=RED}

注解值成功传入到实例化对象中的对应字段,并返回实例化对象给调用者。

Java往期文章

Java全栈学习路线、学习资源和面试题一条龙

如何通过一张图和案例快速学会Java自定义注解?

我心里优秀架构师是怎样的?

免费下载经典编程书籍

原创不易,三联支持:点赞、在看、分享