Java 中的注解(Annotation)

Java 中的注解(Annotation)

  • 一、元注解
    • 1.Java 中的元注解
  • 二、Java 中内置的三大注解
  • 三、自定义注解
    • 1.语法格式
  • 四、反射注解
  • 五、注解的作用
  • 六、总结


  • 所有的注解类型都继承自 java.lang.annotation.Annotation 接口。
  • 注解(Annotation)是一种引用数据类型。编译之后也是生成 xxx.class 文件。
  • 一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。
  • 解析一个类或者方法的注解往往有两种形式
    • 一种是编译期直接的扫描。=====> @Retention(RetentionPolicy.SOURCE)
      • 编译器的扫描指的是编译器在对 java 代码编译字节码的过程中会检测到某个类或者方法被一些注解修饰,这时它就会对于这些注解进行某些处理。典型的就是 @Override 注解。
      • 这一种情况只适用于那些编译器已经熟知的注解类,比如 JDK 内置的几个注解,而你自定义的注解,编译器是不知道你这个注解的作用的,当然也不知道该如何处理,往往只是会根据该注解的作用范围来选择是否编译进字节码文件,仅此而已。
    • 一种是运行期反射。====> @Retention(RetentionPolicy.RUNTIME)

一、元注解

  • 元注解是用于修饰注解的注解,通常用在注解的定义上。
  • 元注解一般用于指定某个注解生命周期以及作用目标等信息。

1.Java 中的元注解

  • @Target:注解的作用目标
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {/*** Returns an array of the kinds of elements an annotation interface* can be applied to.* @return an array of the kinds of elements an annotation interface* can be applied to*/ElementType[] value();
    }
    
    • ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
    • ElementType.FIELD:允许作用在属性字段上
    • ElementType.METHOD:允许作用在方法上
    • ElementType.PARAMETER:允许作用在方法参数上
    • ElementType.CONSTRUCTOR:允许作用在构造器上
    • ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
    • ElementType.ANNOTATION_TYPE:允许作用在注解上
    • ElementType.PACKAGE:允许作用在包上
  • @Retention:注解的生命周期
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {/*** Returns the retention policy.* @return the retention policy*/RetentionPolicy value();
    }
    
    • RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
    • RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
    • RetentionPolicy.RUNTIME:永久保存,可以反射获取
  • @Documented:注解是否应当被包含在 JavaDoc 文档中
  • @Inherited:是否允许子类继承该注解

二、Java 中内置的三大注解

  • @Override
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
    
    • 它没有任何的属性,所以并不能存储任何其他信息。它只能作用于方法之上,编译结束后将被丢弃。仅被编译器可知,编译器在对 java 文件进行编译成字节码的过程中,一旦检测到某个方法上被修饰了该注解,就会去匹对父类中是否具有一个同样方法签名的函数,如果不是,自然不能通过编译。
  • @Deprecated
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
    public @interface Deprecated {String since() default "";boolean forRemoval() default false;
    }
    
    • 可以修饰所有的类型,作用是,标记当前的类或者方法或者字段等已经不再被推荐使用了,可能下一次的 JDK 版本就会删除。
  • @SuppressWarnings

三、自定义注解

1.语法格式

[修饰符列表] @interface 注解类型名{类型 属性() [defauult 值];
}
// 样例
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String name() default "gdb";String[] phoneNumbers() default {};
}
  • 注解当中的属性类型可以是:byte short int long float double boolean char String Class 枚举类型以及以上每一种的数组形式。

四、反射注解

  • 要求必须使用 @Retention(RetentionPolicy.RUNTIME),这样该注解才能够被反射到。
  • 例子:反射类上的 @MyAnnotation 注解。
    • 1.编写自己的注解:

      package annotation1;import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;@Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MyAnnotation {String name() default "gdb";String[] phoneNumbers() default {};
      }	
      
    • 2.在类上使用自己的注解:

      package annotation1;@MyAnnotation(name = "zhangsan", phoneNumbers = {"123456", "654321"})
      public class MyAnnotationTest {}
      
      • 3.通过反射机制来获取指定类上的注解信息:
      package annotation1;import java.util.Arrays;public class ReflectAnnotation {public static void main(String[] args) throws Exception {//获取类Class<?> c = Class.forName("annotation1.MyAnnotationTest");//判断类上面是否有 @MyAnnotationif (c.isAnnotationPresent(MyAnnotation.class)){//获取注解对象MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);//获取注解对象的属性和调用接口没有区别System.out.println(myAnnotation.name() + ", " + Arrays.toString(myAnnotation.phoneNumbers()));}//判断 Date 类上面是否有 @MyAnnotation 这个注解。Class<?> s = Class.forName("java.lang.String");System.out.println(s.isAnnotationPresent(MyAnnotation.class));}
      }
      

五、注解的作用

  • 注解在程序当中等同于一种标记,如果这个元素上有这个注解怎么办,没有这个注解怎么办。

  • 应用场景:假设有这样一个注解,叫做 @Id,这个注解只能出现在类上面,当这个类上有这个注解的时候,要求这个类中必须有一个 int 类型的 id 属性。如果没有这个属性就报异常。如果有这个属性就正常执行。

    • 1.编写 @Id 注解:
    package annotation1;import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;@Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Id {}
    
    • 2.编写异常类:
    package annotation1;public class NotHasIdException extends RuntimeException{public NotHasIdException() {}public NotHasIdException(String message) {super(message);}
    }
    
    • 3.编写使用 @Id 注解的类:
    package annotation1;@Id
    public class IdAnnotationTest {int id;
    }
    
    • 4.通过反射机制来判断是否正确:
    package annotation1;import java.lang.reflect.Field;public class ReflectAnnotation {public static void main(String[] args) throws Exception {//获取类Class<?> c = Class.forName("annotation1.IdAnnotationTest");//判断类上面是否有 @Id 注解if (c.isAnnotationPresent(Id.class)){//当一个类上面有 @Id 注解的时候,要求类中必须存在 int 类型的id属性。//如果没有int类型的id属性则报异常。//获取类的所有属性Field[] fields = c.getDeclaredFields();boolean isOK = false;for(Field field : fields){if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){isOK = true;break;}}//判断是否合法if (!isOK)throw new NotHasIdException("被@Id注解标注的类没有int类型的id属性!!!");}}
    }
    

六、总结

  • 如果一个注解的属性的名字是 value,并且只有一个属性的话,在使用的时候,该属性名可以省略。
  • 如果属性是一个数组,如果数组中只有一个元素,大括号可以省略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/644606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式 格式化excel表格数据

一、从excel表格复制一列数据 二、形成数据格式 ‘4013197767140’,‘5776879019003’, 三、操作 打开编辑器&#xff0c;使用正则匹配

k8s---helm

Helm是什么&#xff1f; 在没有helm之前。部署一个服务&#xff0c;需要deployment、service、ingress、挂在卷等等相关配置都需要人工来配置。 helm的作用就是通过打包的方式&#xff0c;把需要人工编写的配置集成在一起。是一键式的部署服务。类似于yum功能。 由官方提供的…

C++笔记(二)

函数的默认参数 如果我们自己传入数据&#xff0c;就用自己的数据&#xff0c;如果没有&#xff0c;就用默认值 语法&#xff1a; 返回值类型 函数名&#xff08;形参默认值&#xff09;{} int func&#xff08;int a&#xff0c;int b20&#xff0c;int c30&#xff09;{} …

pytorch实战-6手写数字加法机-迁移学习

1 概述 迁移学习概念&#xff1a;将已经训练好的识别某些信息的网络拿去经过训练识别另外不同类别的信息 优越性&#xff1a;提高了训练模型利用率&#xff0c;解决了数据缺失的问题&#xff08;对于新的预测场景&#xff0c;不需要大量的数据&#xff0c;只需要少量数据即可…

2012-2022年全国各省数字经济相关指标数据合集(18个指标)

2012-2022年全国各省数字经济相关指标数据合集&#xff08;18个指标&#xff09; 1、时间&#xff1a;2012-2022年 2、指标&#xff1a;地区、year、互联网接入端口数、互联网宽带接入用户数、互联网域名数、移动电话普及率、长途光缆线路长度&#xff08;万公里&#xff09;…

java开发——《并发编程》

目录 一.jmm 二.并发了什么 1.只有一个核&#xff08;单核&#xff09;并发还有没有意义 2.单核&#xff0c;还有什么可见性问题 3.并发和并行 三.volitaile 1.变量的可见性问题 2.原因是什么 3.本次修改的变量直接刷到主内存 4.声明其他内存对于这个地址的缓存无效 …

highcharts.css文件的样式覆盖了options的series里面的color问题解决

文章目录 一、问题背景二、解决问题 一、问题背景 原本的charts我们的每个数据是有对应的color显示的&#xff0c;如下图&#xff1a; 后面我们系统做了黑白模式&#xff0c;引入了highcharts的css文件&#xff0c;结果highcharts的css文件中class的颜色样式覆盖了我们数据中的…

ChatGPT与文心一言:应用示例与体验比较

ChatGPT 和文心一言哪个更好用&#xff1f; 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映&#xff0c;我将提供一些典型的应用示例。这些示例都取自真实的用户体验&#xff0c;以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…

【云原生】Docker的端口映射、数据卷、数据卷容器、容器互联

目录 一、端口映射&#xff08;相当于添加iptables的DANT&#xff09; 二、数据卷创建&#xff08;宿主机目录或文件挂载到容器中&#xff09; 三、数据卷容器&#xff08;多个容器通过同一个数据卷容器为基点&#xff0c;实现所有容器数据共享&#xff09; 四、容器互联&am…

Java 设计者模式以及与Spring关系(六) 装饰和模版方法模式

简介: 本文是个系列一次会出两个设计者模式作用&#xff0c;如果有关联就三个&#xff0c;除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道设计者模式有3类23种设计模式&#xff0c;标红是特别重要的设计者模式建议都会&#xff0c;而且熟读于心&#…

Deployment介绍

1、Deployment介绍 Deployment一般用于部署公司的无状态服务。 格式&#xff1a; apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metada…

菜鸟导入导出assetbundle

因为菜鸟不会用unity c#什么的&#xff0c;所以最后参考贴吧的方法用的是UABE(Unity Assets Bundle Extractor)和UABEA(Unity Assets Bundle Extractor Avalonia) 可以去github上下载 对于txt、xml什么的可以直接改&#xff0c;但是byte文件里还是会有一些类似乱码的东西&…

Qt5项目拆解第一集解决:中文乱码| 全局字体|注册表|QSS/CSS

# 一、乱码解决代码片段 QTextCodec是Qt中用于处理文本编码和字符集转换的类。它提供了一系列静态函数来实现不同编码的文本转换,包括编码转换、字符集检测和转换、以及数据流中的文本编码处理。QTextCodec类使得Qt可以在不同的编码和字符集之间进行无缝转换,从而方便地处理…

Switch用法以及新特性-最全总结版

本篇文章参考了大佬文章&#xff0c;感谢大佬无私分享&#xff1a; http://t.csdnimg.cn/MjZnX http://t.csdnimg.cn/QFg0x 目录 一、Switch用法&#xff1a;JDK7及以前 1.1、举例一&#xff1a; 1.2、举例二&#xff1a; 二、Switch穿透&#xff1a; 2.1、举例&#xf…

【Linux】常见指令(二)

前言 常见指令第二部分。 文章目录 一、指令&#xff08;下&#xff09;重定向>&#xff1a;输出重定向>>&#xff1a;追加输出<&#xff1a;输入重定向 10. more—显示文本文件内容11.less—逐屏浏览文本文件内容12. head13. tail管道 |14. date—时间指令在这里插…

rust for循环步长-1,反向逆序遍历

fn main() {for i in (0..3).rev().step_by(1) {print!("{}", i);} } // 打印结果&#xff1a;210Trait std::iter::Iterator fn rev(self) -> Rev where Self: Sized DoubleEndedIteratorfn step_by(self, step: usize) -> StepBy where Self: Sized

DI和IOC

依赖注入&#xff08;Dependency Injection, DI&#xff09;和控制反转&#xff08;Inversion of Control, IoC&#xff09;是面向对象编程中的两个重要概念&#xff0c;它们紧密相关并在现代软件开发中经常结合使用。 依赖注入&#xff1a; 依赖注入是一种设计模式&#xff0…

2024年可能会用到的几个地图可视化模板

前言 在数字化的过程中&#xff0c;数据可视化变得越来越重要。用户喜欢通过酷炫的视觉效果和直观的数据展示来理解数据。可视化地图组件是数据可视化的重要组成部分。这些地图组件提供多样化的效果&#xff0c;能够更好地展示数据的关系和地理分布&#xff0c;直观地将数据与…

高高兴兴过春节

一年一度的春节到了&#xff0c;到处洋溢着节日的气氛&#xff0c;到处彩灯高照&#xff0c;鞭炮齐鸣。   早上&#xff0c;我早早地起来和姐姐一起给爷爷奶奶拜年&#xff0c;爷爷很开心给了我一个大大的红包。吃完早饭&#xff0c;妈妈贴春联&#xff0c;爸爸挂灯笼&#x…

裁员潮中的自我成长,小故事,大鼓励

程序员裁员潮&#xff1a;技术变革下的职业危机 科技浪潮滚滚而来&#xff0c;我们了解科技&#xff0c;敬畏科技&#xff0c;拥抱科技。我们怕的不是裁员&#xff0c;而是自己无所适从的样子。 2023年&#xff0c;科技公司裁员的新闻屡见不鲜。据统计&#xff0c;今年以来&…