一篇文章通俗易懂的让你彻底理解 Java 注解
很多Java程序员,对Java的注解一知半解,更有甚者,有的人可能连注解是什么都不知道
本文我们用最简单的 demo , 最通俗最短的语言,带你了解注解到底是什么?
先来简单回顾一下基础,我们知道,Java 的源文件编辑后,生成 .class 文件,
.Java源文件,这个是源文件时期- 源文件经过编译生成
.class字节码文件,这个也是编译时期 .class加载到内存中,就可以用了,这个是运行期间
如下图

记住以上知识点,下面和注解有关,我们正式来讲注解
本文将从以下 2 个方面来讲解注解
- 1 注解是什么
- 2 如何定义一个注解
- 3 如何使用注解
尤其是第3条,很多人不理解注解,就是因为不知道如何使用注解
第3条本文会用最简单的语言来揭示如何使用
一 注解是什么?
一句话,注解就和生活中的标签一样,比如一个人,这个人可能有 学生标签,月光族标签,爱抬杠标签
二 如何定义一个注解
语法: public @interface 注解名 { }
对的, @interface 是个关键字,记住就行了,没有为什么
定义注解就是用@interface ,后面跟上注解名
比如定义一个名字叫 info 的注解,如下
新建一个文件 info.java,代码如下:
package com.demo;
//定义了一个叫做 info 的注解
public @interface info {
}
很简单吧,上面就定义了一个叫做 info 的注解,下面有2个问题来了
第一个: info 注解用在什么地方?
是用到类名上? 还是用在类的字段上 ? 还是用在类的方法上 ?第二个:info 注解生命周期(或叫保留策略,我更喜欢叫生命周期)
注解还有生命周期吗?答案是当然有了前面说过,注解类似标签,一个人可能刚毕业,有
月光族标签,刚毕业赚的少嘛
但是有可能过了 3,4 年,技术好了,工资涨上去了,可能就没有月光族标签了那么标签有几个生命周期呢?就是本文开头讲的,参考上面的图
答案是:3 个 ,分别是源文件期,编译期,运行期
就是说:有的注解存在于源文件期,有的标签存在于编译期,有的标签存在于运行期
::: tip
运行期的注解用的最多,本文着重讲运行期间,源文件期,编译期比较简单
看懂运行期后,可自行学习另外2个
运行期,也就是注解在运行期还存在
:::
我们接下来给 info 注解定义用在类的字段上,并且是存在于运行期间
先上代码,再解释,代码如下:
@Target(ElementType.FIELD) //注解作用在类的字段上
@Retention(RetentionPolicy.RUNTIME) //注解存在于运行期
public @interface info {
}
由上面代码可以看到,出现了 @Target , @Retention 注解,那么 @Target , @Retention又是什么?
答:@Target, @Retention 是元注解,咋又出来一个元注解,可以望文生义:元就是元始的意思,最开始的意思
举个很简单的例子来帮助了解元注解是什么
比如开发一款 IOS APP 软件,用 xcode 这个软件开发,那么 xcode软件又是用什么开发的?
定义一个注解,用元注解
是不是很类似,如下图

看过上面的图应该能理解了,什么是元注解了吧,就是为了定义注解用的,知道怎么用就行了
就比如我们开发软件,要用到各种各样的开发软件的IDE,我们不用管这些IDE软件是哪个软件开发的
我们只需要知道,元注解就相当于IDE,注解就相当于我们开发的软件,就OK了
回到上面的info的定义,我们来解释一下 Target,Retention 这 2 个注解的用处以及能取哪些值
Target 元注解
用处:用来定义注解的用在的地方,比如是用在类上啊,还是用在字段上啊,还是用在方法上啊等
取值:我们列出几个常用的就行,其它的自行下去查义即可,如下
| 取值 | 用在哪 |
|---|---|
| ElementType.TYPE | 类或者接口上 |
| ElementType.FIELD | 类的字段上 |
| ElementType.METHOD | 类的方法上 |
| ElementType.PARAMETER | 方法的参数上 |
Retention 元注解
用处:用来定义注解的生命周期(或叫保留策略,我更喜欢叫生命周期)
取值:就只有3个,如下
| 取值 | 存在于哪个时期 |
|---|---|
| RetentionPolicy.SOURCE | 源文件期 |
| RetentionPolicy.CLASS | 编译期 |
| RetentionPolicy.RUNTIME | 源运行时期 |
::: tip
元注解都是已经定义好的,我们只管用,只管知道怎么用就行
就是我们自定义一个注解时才用到元注解,取几个值,定义一下我们的注解用在哪些地方
存在的时期等,仅此而已
:::
通过上面的叙述,我们小小总结一下
- 注解就是类似标签一样的东西
- 注解定义是用
public @interface 注解名 { } - 注解是有使用的地方和生命周期的
- 注解能用在类上,字段上,方法上,参数上等
- 元注解就是用来定义注解的,就像 xcode 软件是用来开发IOS 软件一样的逻辑
下面我们来讲第三点,也是最重要的一点,我们学会了自定义注解,怎么使用呢?
三 如何使用注解
注解一般是和反射一块用的,不懂反射的,不懂Java的大Class的,一定要看看下面的2篇文章
一篇文章彻底搞懂Java的大Class到底是什么
一篇文章弄懂 Java 反射的使用
我们来扩展一下上面的 info注解,代码如下:
@Target(ElementType.FIELD) //注解作用在类的字段上
@Retention(RetentionPolicy.RUNTIME) //注解存在于运行期
public @interface info {
String job(); //job属性
String comment(); //comment属性
}
对的,你又看到了注解还能定义属性,记住,就按照上面的定义就行了。
主要看怎么用
我们定义一个工人类Worker,如下:
//工人类
public class Worker {
//工人的名字
public String name;
//工人简介方法,打印工作的基本信息
public void show(){
}
}
很简单的一个类,我们在 name 字段上添加我们定义的info注解,如下
public class Worker {
//注解是能给属性传值的,job和comment和info定义中的相呼应,对,属性就是这样用的
@info(job = "工程师",comment = "工作很努力")
public String name;
public void show(){
}
}
上面我们给 name 字段添加了我们自己定义的注解,并且给注解中传了工作的职位是:工程师 ,评价是:工作很努力
我们想在show()方法中,打印出工作的名字,职位,和评价
获取注解中的 job和 comment可以通过反射获取 ,注意看注释,如下
public class Worker {
//注解是能给属性传的,job和comment和定义中的相呼应
@info(job = "工程师",comment = "工作很努力")
public String name;
public void show(){
//1 获取本类的字节码
Class clz = this.getClass();
//2 获取类中定义的字段
Field[] fields = clz.getDeclaredFields();
//3 遍历字段,看看哪个字段有info注解
for (Field field : fields){
//4 判断此字段上是否有 info 注解
info annotation = field.getAnnotation(info.class);
//5 如果不为 null ,说明 field上有info注解
if (annotation != null){
//6 通过info注解,获取info注解中的 job和comment
String job = annotation.job();
String comment = annotation.comment();
//7 打印出来
System.out.println("我是:" + this.name + " 我的职位是:" + job + " 我的评价是:" + comment);
}
}
}
}
通过上面可以看出,使用注解步骤如下:
- 获取类的 Class ,也就是类的字节码
- 获取类的所有字段的字码码数组
- 遍历字段
- 通过
info annotation = field.getAnnotation(info.class)获取字段上对应的注解 - 通过注解,获取注解中传的值
我们再来写一个 main 函数,调用上面那段代码:如下
public class Demo1 {
public static void main(String[] args){
Worker worker = new Worker();
worker.name = "待兔,www.helloworld.net 站长";
worker.show();
}
}
打印如下:
我是:待兔,www.helloworld.net 站长 我的职位是:工程师 我的评价是:工作很努力
本文到此,几乎讲完了,注解的很多其它的东西还没有讲,不过不重要,本文最重要的让你明白什么是注解,怎么定义注解,怎么使用注解
至于注解其它的知识,比如注解怎么用在方法上,用上类上,等等,都是类似,只需要查一下就行了。
网上很多文章 ,只要能通过本文把注解弄明白了,了解注解其它的就简单了。
一篇文章通俗易懂的让你彻底理解 Java 注解的更多相关文章
- (转)深入理解Java注解类型(@Annotation)
背景:在面试时候问过关于注解的问题,工作中也用到过该java的特性,但是也没有深入的了解. 秒懂,Java 注解 (Annotation)你可以这样学 ps:注解最通俗易懂的解释 注解是一系列元数据, ...
- 理解Java注解类型
一. 理解Java注解 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy ...
- 你真的理解Java 注解吗?
你真的理解Java 注解吗? 1.什么是注解? 官方解释: Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java ...
- 深入理解 Java 注解
深入理解 Java 注解 本文内容基于 JDK8.注解是 JDK5 引入的,后续 JDK 版本扩展了一些内容,本文中没有明确指明版本的注解都是 JDK5 就已经支持的注解.
- 深入理解Java注解类型(@Annotation)
http://blog.csdn.net/javazejian/article/details/71860633 出自[zejian的博客] java注解是在JDK5时引入的新特性,鉴于目前大部分框 ...
- 理解java注解
@是java注解,即annotation. 注解功能可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件. Java注解是附加在代码中的一些元信息,用于一些工具在编译 ...
- 【算法】计算一篇文章的单词数(C、Java语言实现)
1. C语言:一个字符一个字符的读取 (有空再贴出来) 2.Java语言:按行读取,并用正则分割成多个单词,再用MapReduce并行计算单词数 (我使用的是ieda,有些地方跟eclipse有点区别 ...
- java基础强化——深入理解java注解(附简单ORM功能实现)
目录 1.什么是注解 2. 注解的结构以及如何在运行时读取注解 2.1 注解的组成 2.2 注解的类层级结构 2.3 如何在运行时获得注解信息 3.几种元注解介绍 3.1 @Retention 3.2 ...
- 深入理解Java 注解原理
*注解的用途 注解(Annotation)是JDK1.5引入的新特性,包含在java.lang.annotation包中,它是附加在代码中的一些元信息,将一个类的外部信息与内部成员联系起来,在编 译. ...
随机推荐
- Day008 三种初始化及内存分析
三种初始化和内存分析 Java内存分析: 堆: 存放new的对象和数组. 可以被所有的线程共享,不会存放别的对象引用. 栈: 存放基本变量类型(会包含这个基本类型的具体数值). 引用对象的变量(会存放 ...
- Day003 JavaDoc
JavaDoc javadoc命令是用来生成自己的Api文档的 参数信息 @author 作者名 @version 版本号 @since 指明需要最早使用的jdk版本 @param 参数名 @retu ...
- 多线程-5.JMM之happens-before原则
a happens-before b 翻译为a操作对b操作是可见的.可见即是指共享变量的更改能获知. 特性:传递性 原则:volatile定义的变量 写操作 happens-before 读操作 同一 ...
- Linux 内核调度器源码分析 - 初始化
导语 上篇系列文 混部之殇-论云原生资源隔离技术之CPU隔离(一) 介绍了云原生混部场景中CPU资源隔离核心技术:内核调度器,本系列文章<Linux内核调度器源码分析>将从源码的角度剖析内 ...
- 前端的MySQL基础
前端MySQL 一.引言 MySQL是一个关系型数据库管理系统,在Web应用方面,MySQL是最好的应用之一.其主要的他点是体积小.速度块.总体成本低.源码开放 二.MySQL的构成 在我们开始学习M ...
- 使用ldap客户端创建zimbra ldap用户的格式
cat << EOF | ldapadd -x -W -H ldap://:389 -D "uid=zimbra,cn=admins,cn=zimbra" dn: ui ...
- [设计模式] 设计模式课程(十二)-- 门面模式(Facade)
概述 也称外观模式 按目的属于结构型模式,按封装属于接口隔离模式 在组件构建过程中,某些接口之间的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口 ...
- top,它们的意思分别是1分钟、5分钟、15分钟内系统的平均负荷。
理解Linux系统负荷 作者: 阮一峰 日期: 2011年7月31日 一.查看系统负荷 如果你的电脑很慢,你或许想查看一下,它的工作量是否太大了. 在Linux系统中,我们一般使用uptime ...
- BUUCTF(十)[GXYCTF2019]Ping Ping Ping 1
BUUCTF系列 /?ip=baidu.com /?ip=baidu.com|ls 正常回显,当cat flag.php时,提示不让输入空格,而且后面还不让出现falg字符 IFS IFS (Inte ...
- 008.Python循环for循环
for 循环 特指用于遍历容器类型数据,(遍历 循环 迭代 都是一个意思)就是把所有的数据一个一个拿出来的过程, while循环有局限性,不能遍历无序容器数据 setvar = {"a&qu ...