1. 简单介绍

注解(也被称为元数据),为我们在代码中加入信息提供了一种形式化的方法。

注解在一定程度上是把元数据与源码文件结合在一起,而不是保存在外部文档中这一大趋势之下所催生的。


它能够提供用来完整的描写叙述程序所需的信息。而这些信息是无法使用Java来表达的。

因此。注解使得我们能够以将编译器来測试和验证的格式。存储有关程序的额外信息。注解能够用来生成描写叙述符文件。甚至是新的类定义。

通过使用注解。我们能够将这些元数据保存在Java源码中,并利用Annotation
API为自己的注解构造处理工具。


注解能够生成更加干净易读的代码以及编译器类型检查等等。

注解(annotation)实在实际的源码级别保存全部的信息,而不是某种凝视性文字(comment),这使得代码更加简洁。便于维护。

2. 注解分类

依照执行机制分类 描写叙述
源代码注解 注解仅仅在源代码中存在,编译成.class文件就不存在了
编译时注解 注解仅仅在源代码和.class文件里都存在(比如:@override)
执行时注解 在执行阶段还起作用,甚至影响执行逻辑的注解(比如:@Autowired)


3. 内置注解:

(1)@override

表示当前的方法定义将覆盖超类中的方法。假设你不小心拼写错误,或者方法签名对不上被覆盖的方法。编译器就会发出错误提示。


(2)@Deprecated

假设程序猿使用了注解为它的元素。那么编译器会发出警告信息。

(3)@SuppressWarnings

关闭不当的编译器警告信息(在java SE5 之前。也能够使用这个注解,只是被忽略不起作用)

4. 基本的语法

4.1 定义注解

能够看到注解的定义非常像接口的定义。

其实,与其它不论什么Java接口一样,注解也会被编译成class文件。

package com.qunar.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
public class Annotation {
// 定义Description注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
// 使用@interface keyword定义注解
public @interface Description{
// 成员以无參无异常方式声明
String desc();
String author();
// 能够使用defaultkeyword为成员指定一个默认值
int age() default 18;
}
}

除了@符号以外,@Description的定义非常像一个接口。

定义注解的时候会须要一些元注解。如@Target和@Retention。@Target用来定义你的注解将用于什么地方(是一个方法上还是一个类上),@Retention用来定义该注解在哪一个级别上可用(在源码上或者是类文件上或者是执行时)。详细以下解说。


4.2 注解元素

注解@Description中包括int元素age,以及String元素desc和author。注解元素能够使用的类型例如以下:
  • 全部基本数据类型(int,float。boolean等)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组
假设你使用了其它类型。那么编译器就会报错。

注意,也不同意使用不论什么包装类型。只是因为自己主动打包的存在,这算不上什么限制。注解也能够作为元素的类型。也就是注解能够嵌套。


4.3 默认值限制

编译器对元素的默认值有些过分的挑剔。

首先。元素不能有不确定的值。也就是说元素必需要么有默认值,要么使用注解时提供元素的值。
其次。对于非基本类型的元素,不管是在源码中声明时,或者是在注解接口中定义默认值时,都不能以null作为其值。为了这个约束,我们仅仅能自定义一些特殊的值,比如空字符串或者负数,来表示某个元素不存在。

4.4 元注解

元注解仅仅负责注解其它的注解。

元注解 參数 描写叙述






@Taget




CONSTRUCTOR 构造器的声明



           表示注解能够用于什么地方




FIELD 域声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 參数声明
TYPE 类,接口或enum声明
LOCAL_VARIABLE 局部变量声明  


@Retention
SOURCE 注解仅仅在源代码中存在。编译成.class文件就不存在了

        表示须要在什么级别保存该注解信息
CLASS 注解仅仅会在.class文件存在,会被VM丢弃
RUNTIME VM将在执行期也保留注解。因此能够通过反射机制读取注解的信息
@Document     将此注解包括在Javadoc中
@Inherited     同意子类继承父类中的注解


4.5 使用注解

语法:@<注解名称>(<成员名1> = <成员值1>。<成员名2> = <成员值2>。...)

package com.qunar.annotation;
 
import com.qunar.annotation.Annotation.Description;
 
public class Student {
private String name;
@Description(desc = "set name for student object" , author = "sjf0115")
public String getName() {
return name;
}
@Description(desc = "get name from student object" , author = "sjf0115", time = "2016-01-11")
public void setName(String name) {
this.name = name;
}
}


5. 解析注解

通过反射机制获取类。函数或者成员上的执行时注解信息,从而实现动态控制程序执行的逻辑。

package com.qunar.annotation;
 
import java.lang.reflect.Method;
 
import com.qunar.annotation.Annotation.Description;
 
public class ParseAnnotation {
public static void main(String[] args){
Class<? > class1 = null;
try {
// 使用类载入器载入类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 推断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的全部方法
Method[] methods = class1.getMethods();
// 遍历全部方法
for (Method method : methods) {
// 推断方法上是否有Description注解
isExits = method.isAnnotationPresent(Description.class);
if(isExits){
Description description = method.getAnnotation(Description.class);
System.out.println("方法注解:" + description.toString());
}//if
}//for
}
}
执行结果:

方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-12, desc=set name for student object, author=sjf0115)
方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-11, desc=get name from student object, author=sjf0115)

package com.qunar.annotation;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
 
import com.qunar.annotation.Annotation.Description;
 
public class ParseAnnotation {
public static void main(String[] args){
Class<?> class1 = null;
try {
// 使用类载入器载入类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 推断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的全部方法
Method[] methods = class1.getMethods();
// 遍历全部方法
for (Method method : methods) {
// 方法上获取全部的注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof Description){
System.out.println("Description注解:" + annotation.toString());
}//if
}//for
}//for
}
}

这两个程序都用到了反射的方法:getMethods()和getAnnotation()。它们都属于AnnotatedElement接口(Class,Method与Field等类都实现了该接口)。getAnnotation()方法返回指定类型的注解对象,在这里就是Description。假设被注解的方法上没有该类型的注解,则返回null值。


















最新文章

  1. C#中string.format用法详解
  2. 单元测试与Nunit的基本使用
  3. button与input[type=”button”]的区别
  4. 通过Unity3d创建二维码(利用zxing2.2)
  5. 关于完整解答Leo C.W博客中名为“我们公司的ASP.NET 笔试题,你觉得难度如何”的所有题目
  6. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
  7. TCP Socket Establish;UDP Send Package Process In Kernel Sourcecode Learning
  8. php redis 分布式类
  9. 【Java基础】List迭代并修改时出现的ConcurrentModificationException问题
  10. quartz spring
  11. drupal 7.23 上传中文命名文件bug
  12. 吃奶酪 洛谷 p1433
  13. 人工智能之一般合一算法Java实现之
  14. 自己制作Chrome便携版实现多版本共存
  15. MyBatis 接口的使用
  16. 基于源码编译openssl
  17. xml与json
  18. fekit 搭建
  19. Manthan, Codefest 16 C. Spy Syndrome 2 字典树 + dp
  20. 案例46-crm练习客户登录

热门文章

  1. iTOP-4412开发板使用
  2. MyBatis学习总结(12)——Mybatis+Mysql分页查询
  3. 洛谷 P2097 资料分发1
  4. Activity启动过程源代码分析
  5. 数据类型的提升(promotion)
  6. Java Web学习总结(7)——HttpServletRequest对象
  7. 人工智能计算器AI Calculator 3.3.0 具体破解思路&amp;amp;教程
  8. Dynamics CRM 2016 Web API 消息列表
  9. 页面事件(Init,Load,PreRender)执行顺序
  10. node的express参数获取