• Annotation(注释) 概述

从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注释)

Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理. 通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。Annotation 可以像修饰符一样被使用, 可用于修饰包,类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在
Annotation 的 “name=value” 对中。Annotation 能被用来为程序元素(类, 方法, 成员变量等) 设置元数据



  • 为什么使用注解

1,注解使得我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息

2,以用来生成描述符文件,甚至或是新的类定义,并且有助于减轻

3,更加干净易读的代码以及编译器类型检查编写样板代码的负担





  • JDK内置注解

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用. 用于修饰它支持的程序元素,三个基本的 Annotation:

@Override: 限定重写父类方法, 该注释只能用于方法,表示一个方法声明打算重写超类中的另一个方法声明。

@Deprecated: 用于表示某个程序元素(类, 方法等)已过时,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择

@SuppressWarnings: 抑制编译器警告。

  1. package linkin;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Calendar;
  5. import java.util.Date;
  6. import java.util.List;
  7.  
  8. /**
  9. *
  10. * @version 1L
  11. * @author LinkinPark
  12. * @since 2014-11-27
  13. * @motto 梦似烟花心似水,同学少年不言情
  14. * @desc ^3个常用的注解
  15. */
  16. @SuppressWarnings("all")
  17. public class Linkin
  18. {
  19.  
  20. @Override
  21. public String toString()
  22. {
  23. return "";
  24. }
  25.  
  26. public void test()
  27. {
  28. Date date = new Date();
  29. int year = date.getYear();
  30. int year1 = Calendar.getInstance().get(Calendar.YEAR);
  31. }
  32.  
  33. @SuppressWarnings("unchecked")
  34. public void test1()
  35. {
  36. List<String> linkin = new ArrayList();
  37. }
  38.  
  39. }
  • 自定义 Annotation

修饰符 @interface 名{

类型 元素名()  [default value]

}

定义新的 Annotation 类型使用 @interface 关键字。Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明. 其方法名和返回值定义了该成员的名字和类型。可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字。没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation



  1. package linkin;
  2.  
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7.  
  8. /**
  9. *
  10. * @version 1L
  11. * @author LinkinPark
  12. * @since 2014-11-27
  13. * @motto 梦似烟花心似水,同学少年不言情
  14. * @desc ^如果Annotation的成员变量名为value的时候,程序中可以直接在Annotation后面的括号里面指定该成员变量的值,无须使用name=value的形式
  15. */
  16. //如果要指定多个作用域,可以传入一个数组@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR })
  17. @Target(ElementType.METHOD)
  18. //一般都是RUNTIME,来运行时通过反射也可以获得这个注解。@Retention(value=RetentionPolicy.RUNTIME)
  19. @Retention(RetentionPolicy.RUNTIME)
  20. public @interface LinkinAnnotation {
  21. String value() default "";
  22. String name() default "";
  23. String[] names();
  24. }
  • JDK 的元 Annotation

JDK 的元 Annotation 用于修饰其他 Annotation 定义

1,@Retention: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间, @Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 @Rentention 时必须为该 value 成员变量指定值:

RetentionPolicy.CLASS: 编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 不会保留注释. 这是默认值

RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行 Java 程序时, JVM 会保留注释. 程序可以通过反射获取该注释

RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释

2,@Target: 用于修饰 Annotation 定义, 用于指定被修饰的 Annotation 能用于修饰哪些程序元素. @Target 也包含一个名为 value 的成员变量



3,@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档

4,@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注释。

上面的元注解经常用到就下面2个:@Target 该注解可以用于哪些地方。@Retention 表示需要在什么级别保存该注解信息







  • 提取 Annotation 信息

JDK 5.0 在 java.lang.reflect 包下新增了 AnnotatedElement 接口, 该接口代表程序中可以接受注释的程序元素

当一个 Annotation 类型被定义为运行时 Annotation 后, 该注释才是运行时可见, 当 class 文件被载入时保存在 class 文件中的 Annotation 才会被虚拟机读取

程序可以调用 AnnotationElement 对象的如下方法来访问 Annotation 信息。







  • 什么是注解处理器

注解本身并不会对程序的编译方式产生影响。注解处理器能够通过在运行时使用反射获取在程序代码中的使用的注解信息,从而实现一些额外的功能。

下面的代码模拟演示juit测试框架:

  1. package com.tanlan.crm.base.ap;
  2.  
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. import java.lang.reflect.Method;
  8.  
  9. /**
  10. *
  11. * @version 1L
  12. * @author LinkinPark
  13. * @since 2014-11-27
  14. * @motto 梦似烟花心似水,同学少年不言情
  15. * @desc ^模拟juit测试框架,即打了test注解的方法能被执行
  16. */
  17. public class AnnoatationProcess {
  18. public void process(TestDemo testDemo) throws Exception {
  19. Class<TestDemo> c = TestDemo.class;
  20. Method[] methods = c.getDeclaredMethods();
  21. for (Method method : methods) {
  22. // 判断方法是否使用了Test注解
  23. if (method.isAnnotationPresent(Test.class)) {
  24. method.invoke(testDemo);
  25. }
  26. }
  27. }
  28.  
  29. public static void main(String[] args) throws Exception {
  30. TestDemo testDemo=new TestDemo();
  31. AnnoatationProcess process=new AnnoatationProcess();
  32. process.process(testDemo);
  33. }
  34. }
  35.  
  36. @Target(ElementType.METHOD)
  37. @Retention(RetentionPolicy.RUNTIME)
  38. @interface Test {
  39.  
  40. }
  41.  
  42. class TestDemo {
  43. @Test
  44. public void test1() {
  45. System.out.println("test1");
  46. }
  47.  
  48. @Test
  49. public void test2() {
  50. System.out.println("test2");
  51. }
  52. }

下面代码模拟了hibernate的实体注解映射:

  1. package com.tanlan.crm.base.ap;
  2.  
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Retention;
  5. import java.lang.annotation.RetentionPolicy;
  6. import java.lang.annotation.Target;
  7. import java.lang.reflect.Field;
  8. import java.lang.reflect.Method;
  9.  
  10. public class DAO {
  11.  
  12. public void add1(User user) throws Exception {
  13. String sql = "insert into ";
  14. String values = "";
  15. Class<User> c = User.class;
  16. if (c.isAnnotationPresent(Table.class)) {
  17. Table t = c.getAnnotation(Table.class);
  18. String tableName = t.value();
  19. if (tableName.equals("")) {
  20. tableName = c.getSimpleName();
  21. }
  22. sql += tableName + "(";
  23. Field[] fields = c.getDeclaredFields();
  24. for (Field field : fields) {
  25. if (field.isAnnotationPresent(Column.class)) {
  26. Column col = field.getAnnotation(Column.class);
  27. String colName = col.value();
  28. if (colName.equals("")) {
  29. colName = field.getName();
  30. }
  31. sql += colName + ",";
  32. Method method = c.getDeclaredMethod("get"
  33. + toUpper(colName));
  34. Object v = method.invoke(user);
  35. values += "'" + v + "',";
  36. }
  37. }
  38. }
  39. sql = sql.substring(0, sql.length() - 1);
  40. sql += ") values(" + values.substring(0, values.length() - 1) + ")";
  41. System.out.println(sql);
  42. }
  43.  
  44. public <E> void add(E e) throws Exception {
  45. String sql = "insert into ";
  46. String values = "";
  47. Class<?> c = e.getClass();
  48. if (c.isAnnotationPresent(Table.class)) {
  49. Table t = c.getAnnotation(Table.class);
  50. String tableName = t.value();
  51. if (tableName.equals("")) {
  52. tableName = c.getSimpleName();
  53. }
  54. sql += tableName + "(";
  55. Field[] fields = c.getDeclaredFields();
  56. for (Field field : fields) {
  57. if (field.isAnnotationPresent(Column.class)) {
  58. Column col = field.getAnnotation(Column.class);
  59. String colName = col.value();
  60. if (colName.equals("")) {
  61. colName = field.getName();
  62. }
  63. sql += colName + ",";
  64. Method method = c.getDeclaredMethod("get"
  65. + toUpper(colName));
  66. Object v = method.invoke(e);
  67. values += "'" + v + "',";
  68. }
  69.  
  70. }
  71.  
  72. }
  73. sql = sql.substring(0, sql.length() - 1);
  74. sql += ") values(" + values.substring(0, values.length() - 1) + ")";
  75. System.out.println(sql);
  76. }
  77.  
  78. private static String toUpper(String s) {
  79. String first = s.substring(0, 1);
  80. return first.toUpperCase() + s.substring(1);
  81. }
  82.  
  83. public static void main(String[] args) throws Exception {
  84. User user=new User();
  85. user.setName("Tom");
  86. user.setPassword("123456");
  87.  
  88. DAO dao=new DAO();
  89. dao.add(user);
  90.  
  91. Product product=new Product();
  92. product.setName("电视");
  93. dao.add(product);
  94.  
  95. }
  96. }
  97.  
  98. @Target(ElementType.TYPE)
  99. @Retention(RetentionPolicy.RUNTIME)
  100. @interface Table {
  101. String value() default "";
  102.  
  103. }
  104.  
  105. @Target(ElementType.FIELD)
  106. @Retention(RetentionPolicy.RUNTIME)
  107. @interface Column {
  108. String value() default "";
  109. }
  110.  
  111. @Table
  112. class User {
  113. @Column("name")
  114. private String name;
  115. @Column
  116. private String password;
  117.  
  118. public String getName() {
  119. return name;
  120. }
  121.  
  122. public void setName(String name) {
  123. this.name = name;
  124. }
  125.  
  126. public String getPassword() {
  127. return password;
  128. }
  129.  
  130. public void setPassword(String password) {
  131. this.password = password;
  132. }
  133.  
  134. }
  135.  
  136. @Table("crm_product")
  137. class Product {
  138. @Column
  139. private String name;
  140.  
  141. public String getName() {
  142. return name;
  143. }
  144.  
  145. public void setName(String name) {
  146. this.name = name;
  147. }
  148.  
  149. }

java注解--Annotation的更多相关文章

  1. Java - 注解 (Annotation)

    Java - 注解 (Annotation)   一.基本的 Annotation     > 使用 Annotation 时要在其前面增加 @符号,并把该 Annotation 当成一个修饰符 ...

  2. Java注解Annotation(一)

    Java注解Annotation(一)——简介 这一章首先简单介绍一下注解,下一章会给出一个注解应用的DEMO. 1. 元注解 元注解的作用是负责注解其他的注解. JDK1.5中,定义了4个标准的me ...

  3. Java注解(Annotation)详解

    转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...

  4. Java注解Annotation与自定义注解详解

    Java注解简介 开发中经常使用到注解,在项目中也偶尔会见到过自定义注解,今天就来探讨一下这个注解是什么鬼,以及注解的应用场景和如何自定义注解. 下面列举开发中常见的注解 @Override:用于标识 ...

  5. 深入JAVA注解-Annotation(学习过程)

    JAVA注解-Annotation学习 本文目的:项目开发过程中遇到自定义注解,想要弄清楚其原理,但是自己的基础知识不足以支撑自己去探索此问题,所以先记录问题,然后补充基础知识,然后解决其问题.记录此 ...

  6. 深入学习JAVA注解-Annotation(学习过程)

    JAVA注解-Annotation学习 本文目的:项目开发过程中遇到自定义注解,想要弄清楚其原理,但是自己的基础知识不足以支撑自己去探索此问题,所以先记录问题,然后补充基础知识,然后解决其问题.记录此 ...

  7. java注解(Annotation)解析

    注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ ...

  8. Java注解Annotation学习

    学习注解Annotation的原理,这篇讲的不错:http://blog.csdn.net/lylwo317/article/details/52163304 先自定义一个运行时注解 @Target( ...

  9. java注解Annotation

    扯扯注解的蛋 为什么学习注解?学习注解有什么好处?学完能做什么? 1.能够读懂别人的代码,特别是框架相关的代码 2.让编程更加简洁,代码更加清晰 3.让别人高看你一眼 注解是java1.5引入的 概念 ...

  10. java 注解Annotation

    什么是注解?  注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的. java注解又叫java标注,java提供了一套机制,使得我们可以对 ...

随机推荐

  1. Mysql无法启动 InnoDB: Attempted to open a previously opened tablespace

    win2008,Mysql5.6,mysql服务无法启动 查看事件日志,报错InnoDB: Attempted to open a previously opened tablespace 最终解决方 ...

  2. python1数据链接总结

    本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...

  3. NoSQL:Linux操作memcached

    一 NoSQL简介 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付 ...

  4. 前端学习:html基础学习四

    7.HTML表格(主要内容<table><caption><tr><th><td>标记) <table>标记 基本格式 < ...

  5. Linux centos7系统下svn的安装与配置

    一.安装svn # yum -y install svn 二.查看svn版本信息 # svnserve --version 三.搭建svn版本库(假设项目名称为project) 1.首先创建版本库目录 ...

  6. Smart-image通过SoftReference提高性能

    文章导读: 文件介绍了常见的图片下载开源插件smart-image, 由于移动设备硬件受限,因此Android的相关app都要考虑到性能的关系, 所以很多的第三方插件都使用到了缓存cache技术,本人 ...

  7. 详解css3弹性盒模型(Flexbox)

    目前没有浏览器支持 box-flex 属性. Firefox 支持替代的 -moz-box-flex 属性. Safari.Opera 以及 Chrome 支持替代的 -webkit-box-flex ...

  8. BZOJ 3211: 花神游历各国【线段树区间开方问题】

    3211: 花神游历各国 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 3514  Solved: 1306[Submit][Status][Discu ...

  9. 51 Nod 1005 大数加法【Java大数乱搞,python大数乱搞】

    1005 大数加法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个大整数A,B,计算A+B的结果. Input 第1行:大数A 第2行:大数B (A,B的长度  ...

  10. c++(排序二叉树插入)

    二叉树的节点插入比较简单.一般来说,二叉树的插入主要分为以下两个步骤: 1) 对当前的参数进行判断,因为需要考虑到头结点,所以我们使用了指针的指针作为函数的输入参数 2) 分情况讨论: 如果原来二叉树 ...