当前位置: 首页 > news >正文

读书笔记-《ON JAVA 中文版》-摘要26[第二十三章 注解]

文章目录

  • 第二十三章 注解
    • 1. 基本语法
      • 1.1 基本语法
      • 1.2 定义注解
      • 1.3 元注解
    • 2. 编写注解处理器
      • 2.1 编写注解处理器
      • 2.2 注解元素
      • 2.3 默认值限制
    • 3. 使用javac处理注解
    • 4. 基于注解的单元测试
    • 5. 本章小结

第二十三章 注解

注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方式,使我们可以在稍后的某个时刻更容易的使用这些数据。

通过使用注解,你可以将元数据保存在 Java 源代码中。并拥有如下有下优势:简单易读的代码,编译器类型检查,使用 annotation API 为自己的注解构造处理工具。

注解的语法十分简单,主要是在现有语法中添加 @ 符号

1. 基本语法

1.1 基本语法

使用 @Test 对 testExecute() 进行注解。该注解本身不做任何事情,但是编译器要保证其类路径上有 @Test 注解的定义。

package annotations;import onjava.atunit.Test;public class Testable {public void execute() {System.out.println("Executing..");}@Testvoid testExecute() { execute(); }
}

1.2 定义注解

注解的定义看起来很像接口的定义。事实上,它们和其他 Java 接口一样,也会被编译成 class 文件。

package onjava.atunit;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}

@Target 定义你的注解可以应用在哪里(例如是方法还是字段)。 @Retention 定义了注解在哪里可用,在源代码中(SOURCE),class文件(CLASS)中或者是在运行时(RUNTIME)。

不包含任何元素的注解称为标记注解(marker annotation),例如上例中的 @Test 就是标记注解。

下面是一个简单的注解,我们可以用它来追踪项目中的用例。

package annotations;import java.util.List;public class PasswordUtils {// 注解的元素在使用时表现为 名-值 对的形式,并且需要放置在 @UseCase 声明之后的括号内。@UseCase(id = 47, description ="Passwords must contain at least one numeric")public boolean validatePassword(String passwd) {return (passwd.matches("\\w*\\d\\w*"));}@UseCase(id = 48)public String encryptPassword(String passwd) {return new StringBuilder(passwd).reverse().toString();}@UseCase(id = 49, description ="New passwords can't equal previously used ones")public boolean checkForNewPassword(List<String> prevPasswords, String passwd) {return !prevPasswords.contains(passwd);}
}

1.3 元注解

Java 语言中目前有 5 种标准注解:

  • @Override:表示当前的方法定义将覆盖基类的方法。如果你不小心拼写错误,或者方法签名被错误拼写的时候,编译器就会发出错误提示。

  • @Deprecated:如果使用该注解的元素被调用,编译器就会发出警告信息。

  • @SuppressWarnings:关闭不当的编译器警告信息。

  • @SafeVarargs:在 Java 7 中加入用于禁止对具有泛型varargs参数的方法或构造函数的调用方发出警告。

  • @FunctionalInterface:Java 8 中加入用于表示类型声明为函数式接口

以及 5 种元注解。元注解用于注解其他的注解

注解解释
@Target表示注解可以用于哪些地方。可能的 ElementType 参数包括:
CONSTRUCTOR:构造器的声明
FIELD:字段声明(包括 enum 实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或者 enum 声明
@Retention表示注解信息保存的时长。可选的 RetentionPolicy 参数包括:
SOURCE:注解将被编译器丢弃
SOURCE:注解将被编译器丢弃
CLASS:注解在 class 文件中可用,但是会被 VM 丢弃。
RUNTIME:VM 将在运行期也保留注解,因此可以通过反射机制读取注解的信
息。
@Documented将此注解保存在 Javadoc 中
@Inherited允许子类继承父类的注解
@Repeatable允许一个注解可以被使用一次或者多次

2. 编写注解处理器

2.1 编写注解处理器

如果没有用于读取注解的工具,那么注解不会比注释更有用。使用注解中一个很重要的部分就是,创建与使用注解处理器。

下面是一个非常简单的注解处理器,我们用它来读取被注解的 PasswordUtils 类,并且使用反射机制来寻找 @UseCase 标记。

package annotations;import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;public class UseCaseTracker {public static voidtrackUseCases(List<Integer> useCases, Class<?> cl) {for (Method m : cl.getDeclaredMethods()) {UseCase uc = m.getAnnotation(UseCase.class);if (uc != null) {System.out.println("Found Use Case " +uc.id() + "\n " + uc.description());useCases.remove(Integer.valueOf(uc.id()));}}useCases.forEach(i ->System.out.println("Missing use case " + i));}public static void main(String[] args) {List<Integer> useCases = IntStream.range(47, 51).boxed().collect(Collectors.toList());trackUseCases(useCases, PasswordUtils.class);}
}

输出:

Found Use Case 47Passwords must contain at least one numeric
Found Use Case 49New passwords can't equal previously used ones
Found Use Case 48no description
Missing use case 50

2.2 注解元素

UseCase.java 中定义的 @UseCase 的标签包含 int 元素 id 和 String 元素 description。注解元素可用的类型如下所示:

  • 所有基本类型(int、float、boolean等)

  • String

  • Class

  • enum

  • Annotation

  • 以上类型的数组

2.3 默认值限制

编译器对于元素的默认值有些过于挑剔。首先,元素不能有不确定的值。也就是说,元素要么有默认值,要么就在使用注解时提供元素的值。

这里有另外一个限制:任何非基本类型的元素, 无论是在源代码声明时还是在注解接口中定义默认值时,都不能使用 null 作为其值。这个限制使得处理器很难表现一个元素的存在或者缺失的状态,因为在每个注解的声明中,所有的元素都存在,并且具有相应的值。为了绕开这个约束,可以自定义一些特殊的值,比如空字符串或者负数用于表达某个元素不存在。

package annotations;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimulatingNull {int id() default -1;String description() default "";
}

注解不支持继承

3. 使用javac处理注解

通过 javac,你可以通过创建编译时(compile-time)注解处理器在 Java 源文件上使用注解,而不是编译之后的 class 文件。

每一个你编写的注解都需要处理器,但是 javac 可以非常容易的将多个注解处理器合并在一起。你可以指定多个需要处理的类,并且你可以添加监听器用于监听注解处理完成后接到通知。

4. 基于注解的单元测试

单元测试是对类中每个方法提供一个或者多个测试的一种事件,其目的是为了有规律的测试一个类中每个部分是否具备正确的行为。在 Java 中,最著名的单元测试工具就是 JUnitJUnit 4 版本已经包含了注解。

5. 本章小结

注解是 Java 引入的一项非常受欢迎的补充,它提供了一种结构化,并且具有类型检查能力的新途径,从而使得你能够为代码中加入元数据,而且不会导致代码杂乱并难以阅读。

而 Javadoc 中的 @deprecated 被 @Deprecated 注解所替代的事实也说明,与注释性文字相比,注解绝对更适用于描述类相关的信息。

Java 提供了很少的内置注解。这意味着如果你在别处找不到可用的类库,那么就只能自己创建新的注解以及相应的处理器。通过将注解处理器链接到 javac,你可以一步完成编译新生成的文件,简化了构造过程。

API 的提供方和框架将会将注解作为他们工具的一部分。通过 @Unit 系统,我们可以想象,注解会极大的改变我们的 Java 编程体验。

在这里插入图片描述
(图网,侵删)

相关文章:

读书笔记-《ON JAVA 中文版》-摘要26[第二十三章 注解]

文章目录 第二十三章 注解1. 基本语法1.1 基本语法1.2 定义注解1.3 元注解 2. 编写注解处理器2.1 编写注解处理器2.2 注解元素2.3 默认值限制 3. 使用javac处理注解4. 基于注解的单元测试5. 本章小结 第二十三章 注解 注解&#xff08;也被称为元数据&#xff09;为我们在代码…...

IDEA报Error:java:无效的源发行版13解决方式

出现问题原因&#xff1a;原本项目是spingboot2.0版本开发的&#xff0c;IDEA启动正常&#xff0c;后期新项目使用spingboot3.0&#xff0c;通过原来的IDEA版本及JDK1.8启动报上述错误&#xff0c;以下为版本文件 解决方式&#xff1a; 项目背景&#xff1a;项目已经上线&…...

基于SpringBoot的健身房管理系统

目录 前言 一、技术栈 二、系统功能介绍 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步…...

竞赛选题 深度学习 植物识别算法系统

文章目录 0 前言2 相关技术2.1 VGG-Net模型2.2 VGG-Net在植物识别的优势(1) 卷积核&#xff0c;池化核大小固定(2) 特征提取更全面(3) 网络训练误差收敛速度较快 3 VGG-Net的搭建3.1 Tornado简介(1) 优势(2) 关键代码 4 Inception V3 神经网络4.1 网络结构 5 开始训练5.1 数据集…...

希尔贝壳受邀参加《人工智能开发平台通用能力要求 第4部分:大模型技术要求》标准第一次研讨会

随着大模型技术与经验的不断累积&#xff0c;该方向也逐渐从聚焦技术突破&#xff0c;到关注开发、部署、应用的全流程工程化落地。为完善人工智能平台标准体系建设&#xff0c;满足产业多样化需求&#xff0c;2023年9月7日&#xff0c;中国信通院云大所在线上召开《人工智能开…...

虹科方案 | AR助力仓储物流突破困境:规模化运营与成本节约

文章来源&#xff1a;虹科数字化AR 点击阅读原文&#xff1a;https://mp.weixin.qq.com/s/xis_I5orLb6RjgSokEhEOA 虹科方案一览 HongKe DigitalizationAR 当今的客户体验要求企业在人员、流程和产品之间实现全面的连接。为了提升整个组织的效率并提高盈利能力&#xff0c;物流…...

spring容器ioc和di

spring ioc 容器的创建 BeanFactory 接口提供了一种高级配置机制&#xff0c;能够管理任何类型的对象&#xff0c;它是SpringIoC容器标准化超接口&#xff01; ApplicationContext 是 BeanFactory 的子接口。它扩展了以下功能&#xff1a; 更容易与 Spring 的 AOP 功能集成消…...

Maven 仓库地址

一、Maven 中央仓库地址 http://www.sonatype.org/nexus/http://mvnrepository.com/ &#xff08;本人推荐仓库&#xff09;http://repo1.maven.org/maven2 二、Maven 中央仓库地址大全 1、阿里中央仓库&#xff08;首选推荐&#xff09; <repository> <id>al…...

【2023研电赛】安谋科技企业命题特别奖:面向独居老人的智能居家监护系统

本文为2023年第十八届中国研究生电子设计竞赛安谋科技企业命题特别奖分享&#xff0c;参加极术社区的【有奖活动】分享2023研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来领&#xff01;&#xff0c;分享2023研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来…...

[Machine learning][Part4] 多维矩阵下的梯度下降线性预测模型的实现

目录 模型初始化信息&#xff1a; 模型实现&#xff1a; 多变量损失函数&#xff1a; 多变量梯度下降实现&#xff1a; 多变量梯度实现&#xff1a; 多变量梯度下降实现&#xff1a; 之前部分实现的梯度下降线性预测模型中的training example只有一个特征属性&#xff1a…...

LCR 078. 合并 K 个升序链表

LCR 078. 合并 K 个升序链表 题目链接&#xff1a;LCR 078. 合并 K 个升序链表 代码如下&#xff1a; class Solution { public:ListNode* mergeKLists(vector<ListNode*>& lists) {ListNode *lsnullptr;for(int i0;i<lists.size();i){lsmergeList(ls,lists[i])…...

JVM面试题:(三)GC和垃圾回收算法

GC: 垃圾回收算法&#xff1a; GC最基础的算法有三种&#xff1a; 标记 -清除算法、复制算法、标记-压缩算法&#xff0c;我们常用的垃圾回收器一般 都采用分代收集算法。 标记 -清除算法&#xff0c;“标记-清除”&#xff08;Mark-Sweep&#xff09;算法&#xff0c;如它的…...

hive建表指定列分隔符为多字符分隔符实战(默认只支持单字符)

1、背景&#xff1a; 后端日志采集完成&#xff0c;清洗入hive表的过程中&#xff0c;发现字段之间的单一字符的分割符号已经不能满足列分割需求&#xff0c;因为字段值本身可能包含分隔符。所以列分隔符使用多个字符列分隔符迫在眉睫。 hive在建表时&#xff0c;通常使用ROW …...

android.app.RemoteServiceException: can‘t deliver broadcast

日常报错记录 android.app.RemoteServiceException: cant deliver broadcast W BroadcastQueue: Cant deliver broadcast to com.broadcast.test(pid 1769). Crashing it.E AndroidRuntime: FATAL EXCEPTION: main E AndroidRuntime: Process: com.broadcast.test, PID: 1769…...

信创办公–基于WPS的EXCEL最佳实践系列 (单元格与行列)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;单元格与行列&#xff09; 目录 应用背景操作步骤1、插入和删除行和列2、合并单元格3、调整行高与列宽4、隐藏行与列5、修改单元格对齐和缩进6、更改字体7、使用格式刷8、设置单元格内的文本自动换行9、应用单元格样式10、插…...

VsCode同时编译多个C文件

VsCode默认只能编译单个C文件&#xff0c;想要编译多个文件&#xff0c;需要额外进行配置 第一种方法 ——> 通过手动指定要编译的文件 g -g .\C文件1 .\C文件2 -o 编译后exe名称 例如我将demo.c和extern.c同时编译得到haha.exe g -g .\demo.c .\extern.c -o haha 第二种…...

Android绑定式服务

Github:https://github.com/MADMAX110/Odometer 启动式服务对于后台操作很合适&#xff0c;不过需要一个更有交互性的服务。 接下来构建这样一个应用&#xff1a; 1、创建一个绑定式服务的基本版本&#xff0c;名为OdometerService 我们要为它增加一个方法getDistance()&#x…...

系统韧性研究(1)| 何谓「系统韧性」?

过去十年&#xff0c;系统韧性作为一个关键问题被广泛讨论&#xff0c;在数据中心和云计算方面尤甚&#xff0c;同时它对赛博物理系统也至关重要&#xff0c;尽管该术语在该领域不太常用。大伙都希望自己的系统具有韧性&#xff0c;但这到底意味着什么&#xff1f;韧性与其他质…...

使用Perl脚本编写爬虫程序的一些技术问题解答

网络爬虫是一种强大的工具&#xff0c;用于从互联网上收集和提取数据。Perl 作为一种功能强大的脚本语言&#xff0c;提供了丰富的工具和库&#xff0c;使得编写的爬虫程序变得简单而灵活。在使用的过程中大家会遇到一些问题&#xff0c;本文将通过问答方式&#xff0c;解答一些…...

SAP内部转移价格(利润中心转移价格)的条件

SAP内部转移价格&#xff08;利润中心转移价格&#xff09; SAP内部转移价格&#xff08;利润中心转移价格&#xff09; SAP内部转移价格&#xff08;利润中心转移价格&#xff09;这个听了很多人说过&#xff0c;但是利润中心转移定价需要具备什么条件。没有找到具体的文档。…...

Netgear路由器急救指南:nmrpflash如何让变砖设备重获新生

Netgear路由器急救指南&#xff1a;nmrpflash如何让变砖设备重获新生 【免费下载链接】nmrpflash Netgear Unbrick Utility 项目地址: https://gitcode.com/gh_mirrors/nmr/nmrpflash 当你心爱的Netgear路由器因为固件升级失败、意外断电或其他原因变成一块"砖头&q…...

制造业数字鸿沟的终结者:零依赖STL到STEP转换引擎的技术突破与应用实践

制造业数字鸿沟的终结者&#xff1a;零依赖STL到STEP转换引擎的技术突破与应用实践 【免费下载链接】stltostp Convert stl files to STEP brep files 项目地址: https://gitcode.com/gh_mirrors/st/stltostp 在数字化制造与工业4.0的浪潮中&#xff0c;制造业企业面临着…...

终极免费方案:3步轻松解锁QQ音乐加密文件,让音乐随处可听

终极免费方案&#xff1a;3步轻松解锁QQ音乐加密文件&#xff0c;让音乐随处可听 【免费下载链接】qmcflac2mp3 直接将qmcflac文件转换成mp3文件&#xff0c;突破QQ音乐的格式限制 项目地址: https://gitcode.com/gh_mirrors/qm/qmcflac2mp3 你是否曾遇到过这样的情况&a…...

3分钟高效恢复Windows 11 LTSC微软商店:完整解决方案指南

3分钟高效恢复Windows 11 LTSC微软商店&#xff1a;完整解决方案指南 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore 你是否在使用Windows 11 24H2 LT…...

智慧树自动刷课终极指南:3分钟快速上手Autovisor免费工具

智慧树自动刷课终极指南&#xff1a;3分钟快速上手Autovisor免费工具 【免费下载链接】Autovisor 2025智慧树刷课脚本 基于Python Playwright的自动化程序 [有免安装版] 项目地址: https://gitcode.com/gh_mirrors/au/Autovisor 还在为智慧树网课的手动操作烦恼吗&#…...

3D打印乐高手机支架:低成本打造高清视频会议摄像头方案

1. 项目概述与核心思路如果你和我一样&#xff0c;对视频会议、直播时笔记本自带摄像头那“感人”的画质感到无奈&#xff0c;同时又觉得单独购买一个高品质的网络摄像头是一笔不小的开销&#xff0c;那么这个项目绝对值得你花上一个周末的时间来折腾。它的核心思路非常巧妙&am…...

PowerInfer:基于热点神经元预测的LLM高性能推理引擎部署指南

1. 项目概述&#xff1a;当推理速度成为AI落地的瓶颈最近在折腾本地大模型推理的朋友&#xff0c;估计都绕不开一个核心痛点&#xff1a;速度。模型效果再好&#xff0c;生成一句话要等上十几秒&#xff0c;那种“卡顿感”足以劝退绝大多数想把它集成到实际应用里的开发者。我自…...

免费开源鼠标连点器终极指南:5分钟掌握高效自动化技巧

免费开源鼠标连点器终极指南&#xff1a;5分钟掌握高效自动化技巧 【免费下载链接】MouseClick &#x1f5b1;️ MouseClick &#x1f5b1;️ 是一款功能强大的鼠标连点器和管理工具&#xff0c;采用 QT Widget 开发 &#xff0c;具备跨平台兼容性 。软件界面美观 &#xff0c;…...

基于CircuitPython与加速度计的魔法9号球:嵌入式交互项目实践

1. 项目概述&#xff1a;当硬件遇上玄学&#xff0c;用代码打造你的专属“决策神器”在嵌入式开发的世界里&#xff0c;我们常常与传感器、显示屏和逻辑代码打交道&#xff0c;构建着一个个解决实际问题的智能设备。但谁说硬件项目就一定要严肃刻板&#xff1f;今天&#xff0c…...

如何用Wedecode实现微信小程序源代码的完美还原:从加密包到可读代码的完整指南

如何用Wedecode实现微信小程序源代码的完美还原&#xff1a;从加密包到可读代码的完整指南 【免费下载链接】wedecode 全自动化&#xff0c;微信小程序 wxapkg 包 源代码还原工具, 线上代码安全审计&#xff0c;支持 Windows, Macos, Linux 项目地址: https://gitcode.com/gh…...