注解的好处:

1.能够读懂别人写的代码,特别是框架相关的代码。

2.本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程更加简洁,代码更加清晰。

3.(重点)刮目相看。
(但是怎么样才能让别人刮目相看呢?会用注解不是目的,最重要的是要使用自定义注解来解决问题。)
举个栗子:
如果面试的时候,你跟老板说你会使用注解,老板觉得你这个人还行;但是如果老板发现你会自定义注解解决问题,老板肯定就会眼前一亮。

更多免费教学文章请关注这里

注解这一概念是在java1.5版本提出的,说Java提供了一种原程序中的元素关联任何信息和任何元数据的途径的方法。

一、Java中的常见注解

1)JDK注解
JDK注解一共分为三类:

JDK注解.png

案例:
我们先新建一个接口people,如下:

1

        <p>2</p><p>3</p><p>4</p><p>5</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>public</code> <code>interface</code> <code>people {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>String name();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>int</code> <code>age();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>void</code> <code>work();</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>然后再建一个类Child实现类people这个接口,并实现该类的方法:</p>

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>12</p><p>13</p><p>14</p><p>15</p></td><td style="vertical-align:baseline;width:586px;"><p><code>public</code> <code>class</code> <code>Child </code><code>implements</code> <code>people {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>@Override</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>String name() {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>return</code> <code>null</code><code>;</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p>&nbsp;</p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>@Override</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>int</code> <code>age() {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>return</code> <code>0</code><code>;</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p>&nbsp;</p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>@Override</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>void</code> <code>work() {</code></p><p>&nbsp;</p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p></td></tr></tbody></table></div><p>看到这里,我们发现这里的所有方法都会加上一个@Override标记,它告诉我们,同时也告诉编译器我们的这些方法肯定覆盖了类people里面的方法的。假如说,我现在把类people里面的某一个方法注释掉:</p>

1

//public String name();

再看类Child里面的name方法就会报错。这样,以后大家看到@Override的时候就能想到这个方法是覆盖了某个接口的方法的。

然后,我们回过头来看类people里面有一个work的方法。这里我们可以理解为人是要工作的,但是并不是所有的人都在工作,那么怎么办呢?如果说这个接口正在用,我们不能删除这个方法,这个时候我们就可以这样:

1

        <p>2</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>@Deprecated</code></p><p><code>public</code> <code>void</code> <code>work();</code></p></td></tr></tbody></table></div><p>@Deprecated标记就表明这个方法已经过时了,在实际中,它又有什么样的应用场景呢?我们在建一个测试类:</p>

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>public</code> <code>class</code> <code>Test {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>void</code> <code>work() {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>people people=</code><code>new</code> <code>Child();</code></p><p><code>!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; people.work();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>这个时候我们会发现<a href="https://www.baidu.com/s?wd=myeclipse&amp;tn=24004469_oem_dg&amp;rsv_dl=gh_pl_sl_csd" target="_blank">myeclipse</a>会给一个警告,并且在work中间出现一个破折号,意思就是这个方法已经过时了。那么问题来了,虽然这个方法过时了,但是我们就是那么傲娇,一定要用它,怎么办呢?只需要这样:</p>

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>public</code> <code>class</code> <code>Test {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>@SuppressWarnings</code><code>(</code><code>"deprecation"</code><code>)</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>void</code> <code>work() {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>people people=</code><code>new</code> <code>Child();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>people.work();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>这样我们就忽略了这个警告。@SuppressWarnings(“deprecation”)就表示我们忽略了deprecation这样的一个警告。</p>

2)Java第三方注解

第三方注解.png

二、注解的分类

1)按照运行机制划分:
【源码注解→编译时注解→运行时注解】

源码注解:只在源码中存在,编译成.class文件就不存在了。

编译时注解:在源码和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他们都属于编译时注解。

运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解。像@Autowired自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。

2)按照来源划分:
【来自JDK的注解——来自第三方的注解——自定义注解】

3)元注解:
元注解是给注解进行注解,可以理解为注解的注解就是元注解。

三、自定义注解

我们分四步来解析自定义注解:
自定义注解的语法要求:

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>@Target</code><code>({ElementType.METHOD,ElementType.TYPE})</code></p><p><code>@Retention</code><code>(RetentionPolicy.RUNTIME)</code></p><p><code>@Inherited</code></p><p><code>@Documented</code></p><p><code>public</code> <code>@interface</code> <code>Description {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>String desc();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>String author();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>int</code> <code>age() </code><code>default</code> <code>18</code><code>;</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>首先我们要明确这不是一个接口,它是使用@interface关键字定义的一个注解。<br>

然后我们看下面的几个方法,String desc();虽然它很类似于接口里面的方法,其实它在注解里面只是一个成员变量(成员以无参无异常的方式声明),int age() default 18;(成员变量可以用default指定一个默认值的)。

最后我们要知道:

①.成员类型是受限制的,合法的类型包括基本的数据类型以及String,Class,Annotation,Enumeration等。

②.如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)。

③.注解类可以没有成员,没有成员的注解称为标识注解。

元注解:

有没有发现上面那段代码有一个没有说呢?没错,它们就是我们所说的元注解:

1

        <p>2</p><p>3</p><p>4</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>@Target</code><code>({ElementType.METHOD,ElementType.TYPE})</code></p><p><code>@Retention</code><code>(RetentionPolicy.RUNTIME)</code></p><p><code>@Inherited</code></p><p><code>@Documented</code></p></td></tr></tbody></table></div><p>我们先看第一行:@Target是这个注解的作用域,<code>ElementType.METHOD</code>是这个注解的作用域的列表,<code>METHOD</code>是方法声明,除此之外,还有:<br><code>CONSTRUCTOR(构造方法声明),FIELD(字段声明),LOCAL VARIABLE(局部变量声明),METHOD(方法声明),PACKAGE(包声明),PARAMETER(参数声明),TYPE(类接口)</code></p>

第二行:@Retention是它的生命周期,前面不是说注解按照运行机制有一个分类嘛,RUNTIME就是在运行时存在,可以通过反射读取。除此之外,还有:
SOURCE(只在源码显示,编译时丢弃),CLASS(编译时记录到class中,运行时忽略),RUNTIME(运行时存在,可以通过反射读取)

第三行:@Inherited是一个标识性的元注解,它允许子注解继承它。

第四行:@Documented,生成javadoc时会包含注解。

使用自定义注解:
使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,…)
案例:

1

        <p>2</p><p>3</p><p>4</p></td><td style="vertical-align:baseline;width:592.667px;"><p><code>@Description</code><code>(desc=</code><code>"i am Color"</code><code>,author=</code><code>"boy"</code><code>,age=</code><code>18</code><code>)</code></p><p><code>public</code> <code>String Color() {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>return</code> <code>"red"</code><code>;</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>这里的Description是我们刚才在自定义注解语法要求里面定义的注解噢,然后我们可以给它的每一个成员变量赋值,注意数据类型。值得注意的是,因为我们前面定义的作用域是在方法和类接口上,所以这个注解在Color()方法上使用是没问题的。</p>

解析注解
概念:
通过反射获取类 、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

准备工作:

Description类.png

Child类.png

接下来,我们就开始测试了:

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>12</p><p>13</p><p>14</p><p>15</p><p>16</p><p>17</p><p>18</p></td><td style="vertical-align:baseline;width:586px;"><p><code>public</code> <code>class</code> <code>ParseAnn {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>try</code> <code>{</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// 使用类加载器加载类</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>Class c = Class.forName(</code><code>"com.test.Child"</code><code>);</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// 找到类上面的注解</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>boolean</code> <code>isExist = c.isAnnotationPresent(Description.</code><code>class</code><code>);</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// 上面的这个方法是用这个类来判断这个类是否存在Description这样的一个注解</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>if</code> <code>(isExist) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>// 拿到注解实例,解析类上面的注解</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>Description d = (Description) c.getAnnotation(Description.</code><code>class</code><code>);</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>System.out.println(d.value());</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>} </code><code>catch</code> <code>(ClassNotFoundException e) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>e.printStackTrace();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>输出的结果:<br><code>i am class annotation</code><br>

可以看到,我们成功的解析了Child类上面的注解。

接下来,我们继续解析方法上的注解:

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p></td><td style="vertical-align:baseline;width:586px;"><p><code>//获取所有的方法</code></p><p><code>Method[] ms = c.getMethods();</code></p><p><code>// 遍历所有的方法</code></p><p><code>for</code> <code>(Method m : ms) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>boolean</code> <code>isExist1 = m.isAnnotationPresent(Description.</code><code>class</code><code>);</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>if</code> <code>(isExist1) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>Description d1=m.getAnnotation(Description.</code><code>class</code><code>);</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>System.out.println(d1.value());</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>输出的结果:<br><code>i am class annotation</code><br><code>i am method annotation</code><br>

可以看到,我们成功的解析了方法上面的注解。

1

        <p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>12</p></td><td style="vertical-align:baseline;width:586px;"><p><code>//另一种解析方法</code></p><p><code>for</code> <code>(Method m : ms) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>//拿到方法上的所有的注解</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>Annotation[] as=m.getAnnotations();</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>for</code> <code>(Annotation a : as) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>//用二元操作符判断a是否是Description的实例</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>if</code> <code>(a </code><code>instanceof</code> <code>Description) {</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>Description d=(Description) a;</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>System.out.println(d.value());</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>&nbsp;&nbsp;&nbsp;&nbsp;</code><code>}</code></p><p><code>}</code></p></td></tr></tbody></table></div><p>也可以得到上面的效果。</p>            </div></div>

Java注解的作用?相关推荐

  1. 【Java 注解】注解简介及作用

    文章目录 一.注解简介 二.注解作用 三.Java 预定义注解 一.注解简介 注释 是使用文字描述程序 , 是 给开发和维护程序的人员看的 , 编译器在编译时会将注释删除 ; 注解 也是用于 描述程序 ...

  2. c JAVA 注解,Java元注解作用及使用

    元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解.Java 5 定义了 4 个注解,分别是 @Documented.@Target.@Retention 和 @Inherited.Ja ...

  3. 彻底搞懂Java注解Annotation(含注解的定义 原则 作用)

    注解的定义 定义 注解:提供一种为程序元素设置元数据的方法. 基本原则:注解不能直接干扰程序代码的运行,无论增加或删除注解,代码都能够正常运行. 注解(也被成为元数据)为我们在代码中添加信息提供了一种 ...

  4. JAVA 注解的几大作用及使用方法详解

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  5. java 注解处理器的作用_深入理解Java:注解(Annotation)--注解处理器

    如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处 ...

  6. Java注解---通俗易懂

    本文转载于Java注解-最通俗易懂的注解 Annotation 中文译过来就是注解.标释的意思,在 Java 中注解是一个很重要的知识点,但经常还是有点让新手不容易理解. 我个人认为,比较糟糕的技术文 ...

  7. (原创)JAVA注解应用——实现属性的自动检测

    一.什么是注解 Annotation(注解)是JDK5.0及以后版本引入的新特性.它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查.注解是以'@注解名'在代码中存在的,根据注解参数的个数 ...

  8. 简述java中的注释以及用法_怎样理解 Java 注解和运用注解编程?

    正好最近在公众号(BetterAndroid)发了一篇关于注解的文章,贴在这里吧,希望对题主有帮助. 一.什么是注解 我们都知道在Java代码中使用注释是为了提升代码的可读性,也就是说,注释是给人看的 ...

  9. 学长告诉你 java注解——深入浅出

    Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制. Java 语言中的类.方法.变量.参数和包等都可以被标注.和 Javadoc 不同,Java 标注可 ...

最新文章

  1. asp.net中缓存的使用介绍一
  2. 【学习笔记】Tableau安装与界面介绍
  3. Iptables Layer7禁止QQ、MSN、p2p软件(解决iptable 无法启动)
  4. Java技术分享:void的用法和意义
  5. iPhone 越狱开发相关
  6. 第一次训练赛的相关总结和教训!
  7. 收藏 | 卷积神经网络中十大拍案叫绝的操作
  8. sql server的搜索_在SQL Server中进行全文本搜索
  9. Python 多线程7-线程通信
  10. 非平衡电桥电阻计算_微安表内阻值对热敏电阻温度计设计的影响
  11. FC SAN - 光纤通道存储区域网络
  12. 欧洲商学院MBA(项目管理)学习笔记
  13. java 线程强制执行join
  14. nginx做域名映射到指定端口(阿里云服务器、阿里域名服务)
  15. 从字节中取出1bit数据
  16. ptp精准时间协议_PTP高精度时间同步协议
  17. Word 2010版本
  18. 虚拟机配置windows7+office2010
  19. 2022-03-06:金币路径。 给定一个数组 A(下标从 1 开始)包含 N 个整数:A1,A2,……,AN 和一个整数 B。 你可以从数组 A 中的任何一个位置(下标为 i)跳到下标 i+1,i+
  20. 关于C#程序无故退出

热门文章

  1. What's the difference between forever and for good?
  2. error: Program received signal SIGSEGV, Segmentation fault. (Codeblocks, C++)
  3. 问题二:用C++输出第一张图片
  4. mysql 前沿表设计_史上最简单MySQL教程详解(基础篇)之表的维护和改造
  5. 数据分析的数据来源于哪
  6. 大数据分析需备哪些技能
  7. Tensorflow2.0入门教程(一)
  8. PHP mysql问号通配符个数_php – MySQL:计算每个条目的LIKE匹配数
  9. oracle数据库查询下级_Oracle 图技术
  10. L2-018 多项式A除以B(模拟)