【JAVA重要知识 | 第八篇】Java注解总结

news2025/1/10 20:43:09

在这里插入图片描述

文章目录

  • 8.注解
    • 8.1注解的定义
      • 8.1.1何为注解?
      • 8.1.2何为元数据和元编程?
        • (1)元数据
        • (2)元编程
        • (3)总结
    • 8.2注解的分类
      • 8.2.1常用的注解
      • 8.2.2自定义注解
      • 8.2.3元注解
        • (1)@Retention
        • (2)@Target
        • (3)@Documented
        • (4)@Inherited
        • (5)@Repeatable
    • 8.3注解的源码分析
    • 8.4注解的作用
      • 8.4.1XML与注解的区别
      • 8.4.2注解的作用

8.注解

8.1注解的定义

8.1.1何为注解?

  • 官网定义:Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。

将上面的话再翻译一下,如下:

  1. 元数据在开发中的作用就是 做数据约束和标准定义,可以将其理解成代码的规范标准(代码的模板);
  2. 代码的模板(元数据)不直接影响代码的执行,它只是帮助我们来更快捷的开发;

综上,注解是一种元数据,可以将它理解为注释、解释,它为我们在代码中添加信息提供了一种形式化的方法,它用于帮助我们更快捷的写代码。

8.1.2何为元数据和元编程?

(1)元数据

元数据主要是做数据类型约束接口定义方法签名定义的作用。 大概的开发流程就是:

  1. 定义元数据,比如定义一个实体,描述这个实体的属性字段名称,类型,长度等信息。根据这些信息构造成一个规范的xml文件。
  2. 根据上一步构造的xml文件,也就是这里所指的元数据。(使用一些魔法,雾)使用公司定制化开发的eclipse插件,用这些xml文件生成标准的Java pojo 和 Java interface。然后标准和实体已经定义完成就可以进行具体的方法和接口的实现。

所以说在这里,元数据在应用中的开发中的作用就是做数据约束和标准定义。这样的开发模式可以说是非常好的一个思路。

作用:

  1. 标准化了开发流程,对数据本身有了一个明确的约束。有利于后期的开发维护。
  2. 减少了重复,意义不大的工作,不需要手动对 Java pojo 和 Java interface 的定义。直接使用元数据来生成对应的Java class 即可。
  3. 由于元数据的规范化,其实在此基础上的扩展能力有了很大的想象力。比如实体的合法校验 支持 jsr 303 (bean validation)规范等等。
(2)元编程

在Java世界的元编程,其实很简单的说就是注解(annotation)的应用

这里的就有很多样例了,比如大名鼎鼎的lombok和spring里面的各种注解。为什么这里还将lombok和spring的注解做区分呢?因为这里的元编程应用时期不同:

  1. lombok 应用于编译期,在java编译生成class文件时,会"偷偷改掉"我们的代码模样,生成对应的模板代码(JSR 269: Pluggable Annotation Processing API)
  2. spring等其他注解主要是在运行期(不敢保证所有的都是在运行时的)。在运行时会调用对应的注解处理器处理对应的逻辑。这里的目的主要是减少模板代码,显得代码过于啰嗦、臃肿。
(3)总结

元编程和元数据的理念都有一个共同的特点,就是减少模板代码,使用代码生成代码的思路去降低工作中繁杂、无用或者意义不大的工作任务。这是极其值得推广的思路,尤其在大型工程面前,可以省下的工作量就非常可观,而且代码量会更少,质量还会更好,也是印证了 less is more 的设计哲学。

8.2注解的分类

在Java中,常用的注解可以分为三类:

  1. Java自带的标准注解:包括@Override、@Deprecated、@SuppressWarnings等,使用这些注解后编译器就会进行检查。

  2. 元注解:元注解是用于定义注解的注解,包括@Retention:表示注解的生效范围

    @Target :表示注解作用的对象

    @Documented :表示可以生成文档

    @Inherited:表示注解可以遗传

    @Native:表示该注解是使用的本地的方法

    @Repeate:表示该注解在同一位置可以重用

    元注解也是Java自带的标准注解,只不过用于修饰注解,比较特殊。

  3. 自定义注解:用户可以根据自己的需求定义注解。

8.2.1常用的注解

@Override         //在需要注解的方法上面@Override即可
protected void onCreate() {
      
}
  1. @Deprecated – 所标注内容不再被建议使用;
  2. @Override – 只能标注方法,表示该方法覆盖父类中的方法;
  3. @Documented --所标注内容可以出现在javadoc中;
  4. @Inherited – 只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性
  5. @Retention – 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性;
  6. @Target – 只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性;
  7. @SuppressWarnings – 所标注内容产生的警告,编译器会对这些警告保持静默;
  8. interface – 用于定义一个注解;

8.2.2自定义注解

注意:自定义注解需要与元注解搭配使用!!!

  • 使用@interface关键字实现自定义注解
public @interface MyTestAnnotation {

}
  • 使用自定义注解
@MyTestAnnotation
public class Test {
   @MyTestAnnotation
   public static void testString(){
   }
}

8.2.3元注解

常用的元注解有@Retention、 @Target、 @Document、 @Inherited和@Repeatable五个。

(1)@Retention
  • 作用:表示注解存在阶段是保留在源码(编译期),字节码(类加载)或者运行期(JVM中运行)

  • 在@Retention注解中使用枚举RetentionPolicy来表示注解保留时期

    • @Retention(RetentionPolicy.SOURCE),注解仅存在于源码中,在class字节码文件中不包含
    • @Retention(RetentionPolicy.CLASS), 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
    • @Retention(RetentionPolicy.RUNTIME), 注解会在class字节码文件中存在,在运行时可以通过反射获取到

若我们自定义注解,则通过前面分析,我们自定义注解如果只存着源码中或者字节码文件中就无法发挥作用,而在运行期间能获取到注解才能实现我们目的,所以自定义注解中肯定是使用 @Retention(RetentionPolicy.RUNTIME),如下:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyTestAnnotation {
}
(2)@Target
  • @Target:定义注解作用的范围,可以是类,方法,方法参数变量等,同样也是通过枚举类ElementType表达作用类型:
    • @Target(ElementType.TYPE) 作用接口、类、枚举、注解
    • @Target(ElementType.FIELD) 作用属性字段、枚举的常量
    • @Target(ElementType.METHOD) 作用方法
    • @Target(ElementType.PARAMETER) 作用方法参数
    • @Target(ElementType.CONSTRUCTOR) 作用构造函数
    • @Target(ElementType.LOCAL_VARIABLE)作用局部变量
    • @Target(ElementType.ANNOTATION_TYPE)作用于注解(@Retention注解中就使用该属性)
    • @Target(ElementType.PACKAGE) 作用于包
    • @Target(ElementType.TYPE_PARAMETER) 作用于类型泛型,即泛型方法、泛型类、泛型接口 (jdk1.8加入)
    • @Target(ElementType.TYPE_USE) 类型使用.可以用于标注任意类型除了 class (jdk1.8加入)

一般比较常用的是ElementType.TYPE类型,如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
    
}
(3)@Documented

Document的英文意思是文档。它的作用是能够将注解中的元素包含到 Javadoc 中去

(4)@Inherited

Inherited的英文意思是继承,但是这个继承和我们平时理解的继承大同小异,一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解。

(5)@Repeatable

Repeatable的英文意思是可重复的。顾名思义说明被这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义。

8.3注解的源码分析

  • 查看@Override源码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

我们看到@Override注解就是通过@interface注解定义的一个普通注解,而我们知道,使用 @interface 定义注解时,意味着它实现了 java.lang.annotation.Annotation 接口,即该注解就是一个Annotation

  1. Annotation 接口的实现细节都由编译器完成。
  2. 通过 @interface 定义注解后,该注解不能继承其他的注解或接口
public interface Annotation {
    boolean equals(Object var1);

    int hashCode();

    String toString();

    Class<? extends Annotation> annotationType();
}

注解本身就是Annotation接口的子接口,也就是说注解中其实是可以有属性和方法,但是接口中的属性都是static final的,对于注解来说没什么意义,而我们 定义接口的方法就相当于注解的属性,也就对应了前面说的为什么注解只有属性成员变量,其实他就是接口的方法,这就是为什么成员变量会有括号,不同于接口我们可以在注解的括号中给成员变量赋值。

根据上述的源码分析,我们得出Java注解(Annotation)的架构如下:

在这里插入图片描述

8.4注解的作用

8.4.1XML与注解的区别

  • xml:是一种集中式的元数据,与源代码无绑定

  • 注解:是一种分散式的元数据,与源代码紧绑定。

8.4.2注解的作用

  1. 生成文档,通过代码里标识的元数据生成javadoc文档。
  2. 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。
  3. 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。
  4. 运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例

在这里插入图片描述

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

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

相关文章

轻松掌握锁冲突问题的排查方法——《OceanBase诊断系列》之八

1. 前言 OceanBase数据库通过两阶段封锁机制确保读写事务并发控制的正确性。在高冲突场景下&#xff0c;事务处理中经常会遇到行锁冲突的问题。然而&#xff0c;许多OceanBase用户对于何时发生锁冲突&#xff0c;锁冲突的表现如何&#xff0c;以及如何排查锁冲突的原因&#x…

python爬虫(6)之处理数组

1、拆分数组 1、spilt&#xff08;&#xff09;函数 此函数的用处是将数组均分成几个数组 演示如下&#xff1a; import numpy as np ac np.array([1,2,8,9,3,5,5,8]) ac1 np.split(ac,2) ac2 np.split(ac,[3,6]) print(ac1,ac2) 结果如下&#xff1a; 其中若是一个数…

【计算机视觉】目标跟踪任务概述和算法介绍

一、前言 1.1&#xff1a;目标跟踪VS目标检测&#xff1a;区别和联系 区别&#xff1a; 任务目标 目标跟踪任务的目标是在视频序列中跟踪一个特定目标的位置&#xff0c;即给定第一帧中的目标位置后&#xff0c;在后续帧中确定目标的位置。而目标检测任务的目标是在静态图像中…

解决 Node.js 中 npm ERR! errno CERT_HAS_EXPIRED问题

出自 BV1MN411y7pw&#xff0c; P94 黑马AJAX-Node.js-Webpack教学视频中npm包下载dayjs出错情况 输入 npm i dayjs指令之后出错&#xff1a; npm ERR! errno CERT_HAS_EXPIREDnpm ERR! A complete log of this run can be found in: C:\Users\24541\AppData\Local\npm-cache…

【leetcode C++】最小栈

leetcode 155. 最小栈 题目 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获…

lspci详解

lspci的作用 lspci是一个Linux命令&#xff0c;用于列出系统中的PCI总线设备信息。PCI&#xff08;Peripheral Component Interconnect&#xff09;是一种常见的计算机总线标准&#xff0c;用于连接各种外部设备&#xff08;如网卡、显卡、声卡等&#xff09;到计算机主板上。…

【CVPR2024】ReID3D:首个使用激光雷达行人充实别 ReID 的工作!

【2024 行人重识别最新进展】ReID3D&#xff1a;首个关注激光雷达行人 ReID 的工作&#xff01; 摘要&#xff1a;数据集&#xff1a;方法模型&#xff1a;多任务预训练&#xff1a;ReID Network&#xff1a; 实验结果&#xff1a;结论&#xff1a; 来源&#xff1a;Arxiv 2023…

mysql中 COALESCE和CASE WHEN的使用以及创建或替换视图

create or replace view 自理能力评估视图 as SELECT ehr_zlnlpg.ID AS ID, ehr_zlnlpg.GRID AS GRID, ehr_zlnlpg.TJID AS TJID, ehr_grjbxx.Name AS 姓名, ehr_grjbxx.Sex AS 性别, ehr_grjbxx.Cardnum AS 身份证号, ehr_zlnlpg.SCORESUM AS 总…

设计模式学习笔记 - 规范与重构 - 5.如何通过封装、抽象、模块化、中间层解耦代码?

前言 《规范与重构 - 1.什么情况下要重构&#xff1f;重构什么&#xff1f;又该如何重构&#xff1f;》讲过&#xff0c;重构可以分为大规模高层重构&#xff08;简称 “大型重构”&#xff09;和小规模低层次重构&#xff08;简称 “小型重构”&#xff09;。大型重构是对系统…

UI自动化测试使用场景及脚本录制

经常有人会问&#xff0c;什么样的项目才适合进行UI自动化测试呢&#xff1f;UI自动化测试相当于模拟手工测试&#xff0c;通过程序去操作页面上的控件。而在实际测试过程中&#xff0c;经常会遇到无法找到控件&#xff0c;或者因控件定义变更而带来的维护成本等问题。 哪些场…

MySQL 事务的原理以及长事务的预防和处置

transaction_isolation 隔离级别 读未提交 读提交 视图是在每个 SQL 语句开始执行的时候创建的 可重复读 视图是在事务启动时创建的&#xff0c;整个事务存在期间都用这个视图 串行化…

目标检测算法

图像识别三大任务 目标识别&#xff1a;或者说分类&#xff0c;定性目标&#xff0c;确定目标是什么目标检测&#xff1a;定位目标&#xff0c;确定目标是什么以及位置目标分割&#xff1a;像素级的对前景与背景进行分类&#xff0c;将背景剔除 目标检测定义 识别图片中有哪…

数据结构与算法第四套试卷(青科大)

1.图 无向图入度出度之和 所有入度之和为2*边数 2.树 **知识点&#xff1a;**注意二叉排序树&#xff01;深度平衡树&#xff0c;所以可能会出现极端现象&#xff08;链表&#xff09;&#xff0c;时间复杂度为0(n)&#xff0c;如果为最好情况即为0(logn) 3.图 1.邻接表n个…

STM32利用标准库编写同时输出4路PWM信号的程序(Proteus)仿真

先看看结果&#xff1a; 这个是根据上午发的文章的基础上更改的&#xff0c;很简单&#xff0c;只是用了一个定时器&#xff0c;初始化了4个比较器而已&#xff0c;就可以单独的控制每一路PWM的占空比了&#xff0c;好了&#xff0c;把源文件展示一下&#xff0c;完事去接孩子放…

Wilson威尔逊平滑

1、威尔逊平滑引入的动机 在曝光很少的情况下&#xff0c;计算出的CTR并不真实可靠&#xff0c;而样本数越大&#xff0c;CTR的比例才越准确&#xff0c;更能反应真实情况。 为了衡量样本数对于CTR信区间的影响&#xff0c;我们引入"威尔逊&#xff08;Wilson&#xff0…

2024暑期实习八股笔记

文章目录 自我介绍MySQL索引索引种类、B树聚簇索引、非聚簇索引联合索引、最左前缀匹配原则索引下推索引失效索引优化 日志、缓冲池redo log&#xff08;重做日志&#xff09;刷盘时机日志文件组 bin log&#xff08;归档日志&#xff09;记录格式写入机制 两阶段提交undo log&…

骨传导耳机如何选购?新手必看的6个避雷小妙招!

在短短几年内&#xff0c;骨传导耳机的市场规模一路攀升&#xff0c;今年甚至有望成为最受欢迎的蓝牙耳机款式&#xff0c;但与此同时&#xff0c;整个骨传导耳机行业也频繁出现乱象&#xff0c;不专业产品鱼龙混杂&#xff0c;令人吃惊的是&#xff0c;还有许多中小网红品牌也…

ctfshow web入门 php特性总结

1.web89 intval函数的利用&#xff0c;intval函数获取变量的整数值&#xff0c;失败时返回0&#xff0c;空的数组返回&#xff0c;非空数组返回1 num[]1 intval ( mixed $var [, int $base 10 ] ) : int Note: 如果 base 是 0&#xff0c;通过检测 var 的格式来决定使用的进…

【Redis】RedisTemplate序列化传输数据

使用自定义的序列化器 使用RedisTemplate默认的序列化器发送数据&#xff0c;会将key全都当成Object处理&#xff0c;从而按照对象的方式转成json格式发送到服务器&#xff0c;这样会导致两个问题。一是不方便阅读&#xff0c;二是会大大浪费内存。因此&#xff0c;建议自定义…

SQLiteC/C++接口详细介绍(一)

上一篇&#xff1a;SQLiteC/C接口简介 下一篇&#xff1a;SQLiteC/C接口详细介绍&#xff08;二&#xff09; 引言&#xff1a; SQLite C/C 数据库接口是一个流行的SQLite库使用形式&#xff0c;它允许开发者在C和C代码中嵌入 SQLite 基本功能的解决方案。通过 SQLite C/C 数据…