1.可以读懂别人写的代码,特别是框架相关的代码。java
2.原本可能须要不少配置文件,须要不少逻辑才能实现的内容,就可使用一个或者多个注解来替代,这样就使得编程更加简洁,代码更加清晰。面试
3.(重点)另眼相看。
(可是怎么样才能让别人另眼相看呢?会用注解不是目的,最重要的是要使用自定义注解来解决问题。)
举个栗子:
若是面试的时候,你跟老板说你会使用注解,老板以为你这我的还行;可是若是老板发现你会自定义注解解决问题,老板确定就会眼前一亮。编程
注解这一律念是在java1.5版本提出的,说Java提供了一种原程序中的元素关联任何信息和任何元数据的途径的方法。框架
1)JDK注解
JDK注解一共分为三类:eclipse
JDK注解.pngide
案例:
咱们先新建一个接口people,以下:函数
1测试 2spa 33d 4 5 |
|
而后再建一个类Child实现类people这个接口,并实现该类的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
看到这里,咱们发现这里的全部方法都会加上一个@Override标记,它告诉咱们,同时也告诉编译器咱们的这些方法确定覆盖了类people里面的方法的。假如说,我如今把类people里面的某一个方法注释掉:
1 |
|
再看类Child里面的name方法就会报错。这样,之后你们看到@Override的时候就能想到这个方法是覆盖了某个接口的方法的。
而后,咱们回过头来看类people里面有一个work的方法。这里咱们能够理解为人是要工做的,可是并非全部的人都在工做,那么怎么办呢?若是说这个接口正在用,咱们不能删除这个方法,这个时候咱们就能够这样:
1 2 |
|
@Deprecated标记就代表这个方法已通过时了,在实际中,它又有什么样的应用场景呢?咱们在建一个测试类:
1 2 3 4 5 6 |
|
这个时候咱们会发现myeclipse会给一个警告,而且在work中间出现一个破折号,意思就是这个方法已通过时了。那么问题来了,虽然这个方法过期了,可是咱们就是那么傲娇,必定要用它,怎么办呢?只须要这样:
1 2 3 4 5 6 7 |
|
这样咱们就忽略了这个警告。@SuppressWarnings(“deprecation”)就表示咱们忽略了deprecation这样的一个警告。
2)Java第三方注解
第三方注解.png
1)按照运行机制划分:
【源码注解→编译时注解→运行时注解】
源码注解:只在源码中存在,编译成.class文件就不存在了。
编译时注解:在源码和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他们都属于编译时注解。
运行时注解:在运行阶段还起做用,甚至会影响运行逻辑的注解。像@Autowired自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。
2)按照来源划分:
【来自JDK的注解——来自第三方的注解——自定义注解】
3)元注解:
元注解是给注解进行注解,能够理解为注解的注解就是元注解。
咱们分四步来解析自定义注解:
自定义注解的语法要求:
1 2 3 4 5 6 7 8 9 |
|
首先咱们要明确这不是一个接口,它是使用@interface关键字定义的一个注解。
而后咱们看下面的几个方法,String desc();
虽然它很相似于接口里面的方法,其实它在注解里面只是一个成员变量(成员以无参无异常的方式声明),int age() default 18;
(成员变量能够用default指定一个默认值的)。
最后咱们要知道:
①.成员类型是受限制的,合法的类型包括基本的数据类型以及String,Class,Annotation,Enumeration等。
②.若是注解只有一个成员,则成员名必须取名为value(),在使用时能够忽略成员名和赋值号(=)。
③.注解类能够没有成员,没有成员的注解称为标识注解。
元注解:
有没有发现上面那段代码有一个没有说呢?没错,它们就是咱们所说的元注解:
1 2 3 4 |
|
咱们先看第一行:@Target是这个注解的做用域,ElementType.METHOD
是这个注解的做用域的列表,METHOD
是方法声明,除此以外,还有:CONSTRUCTOR(构造方法声明),FIELD(字段声明),LOCAL VARIABLE(局部变量声明),METHOD(方法声明),PACKAGE(包声明),PARAMETER(参数声明),TYPE(类接口)
第二行:@Retention是它的生命周期,前面不是说注解按照运行机制有一个分类嘛,RUNTIME
就是在运行时存在,能够经过反射读取。除此以外,还有:SOURCE(只在源码显示,编译时丢弃),CLASS(编译时记录到class中,运行时忽略),RUNTIME(运行时存在,能够经过反射读取)
第三行:@Inherited是一个标识性的元注解,它容许子注解继承它。
第四行:@Documented,生成javadoc时会包含注解。
使用自定义注解:
使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,…)
案例:
1 2 3 4 |
|
这里的Description是咱们刚才在自定义注解语法要求里面定义的注解噢,而后咱们能够给它的每个成员变量赋值,注意数据类型。值得注意的是,由于咱们前面定义的做用域是在方法和类接口上,因此这个注解在Color()方法上使用是没问题的。
解析注解
概念:
经过反射获取类 、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
Description类.png
Child类.png
接下来,咱们就开始测试了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
输出的结果:i am class annotation
能够看到,咱们成功的解析了Child类上面的注解。
接下来,咱们继续解析方法上的注解:
1 2 3 4 5 6 7 8 9 10 |
|
输出的结果:i am class annotation
i am method annotation
能够看到,咱们成功的解析了方法上面的注解。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
也能够获得上面的效果