【1】注解介绍

1)注解是什么?

注解(元数据)是 java提供的一种对程序元素(如类,方法,变量)打标记的方法;以便运行程序或编译器可以识别这些元素进行特殊处理;最典型的用法是,框架代码启动时扫描某注解修饰的所有类并将其加载到内存,以构建系统底层框架,更直白点,类,方法,变量被注解修饰后,更容易被识别以便加载;

补充: 显然,开发或学习底层框架的同学肯定必不可少要学习注解;所以注解是相当重要的;


【2】java内置的三种注解

1)@Override: 表示被标记的方法将覆盖超类中的方法;

2)@Deprecated:表示被标记的元素(类或方法)被废弃了 ; 如果代码使用该元素,则编译器会发出警告;

3)@SuppressWarnings:关闭不当的编译器警告信息;


【3】4种标准元注解

1)元注解:元注解的作用是负责修饰其他注解(参与其他注解的定义或声明)。 java5.0 定义了4个标准的元注解类型; (干货——你也可以认为被注解修饰,就是被注解打标记

1.1)@Target元注解,用于指定被修饰注解可以应用到哪些元素上;

如 注解可以被应用到 packages,type(类,接口,枚举,Annotation类),类型成员(方法,构造方法,成员变量,枚举值),方法参数和本地变量等;

注解定义例子1:

@Target(ElementType.METHOD) // 表示用于修饰(标记)方法
@Retention(RetentionPolicy.RUNTIME) // 表示运行时可用
public @interface Test {} ///:~

注解应用例子1:

public class Testable {public void execute() {System.out.println("Executing..");}@Test  // Test 注解用于修饰方法void testExecute() {execute();}
}

1.2)@Retention元注解,用于指定被修饰注解的生命周期;

  • SOURCE:源文件有效;被编译器丢弃;
  • CLASS:class文件有效;被JVM丢弃;
  • RUNTIME :运行时有效(常用);VM将在运行期也保留注解,通过反射机制读取注解;

1.3)@Document  用于指定被修饰的注解可以被 javadoc 工具文档化;

1.4)@Inherited   用于指定被修饰的注解是可以被继承的

2)上面例子中修饰的注解 Test,是没有任何成员方法的。下面我们来看有成员方法的注解UseCase;·

// 下面定义了一个注解UseCase:该注解作用于方法,该注解在运行时发挥作用
// 该注解UseCase应用于什么地方
@Target(ElementType.METHOD)
// 该注解UseCase的应用级别,源代码-SOURCE, 类文件中-CLASS, 运行时-RUNTIME
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {public int id();public String description() default "no description"; // no description 是默认值
}
/*
D:\workbench_idea\study4vw\thinkinjava\src>javap chapter20.UseCase
Compiled from "UseCase.java"
public interface chapter20.UseCase extends java.lang.annotation.Annotation {public abstract int id();public abstract java.lang.String description();
}
*/

反编译(javap)后的源码:可以看到,注解就是一个接口,该接口的父类是 Annotation 注解接口类型,当然了,接口中的方法都是抽象方法。

2.1)使用 UseCase注解;

// 荔枝-有3个方法被注解UseCase修饰为用例
public class PasswordUtils {// 将 UseCase 注解作用于方法@UseCase(id = 47, description = "validatePassword method")public boolean validatePassword(String password) {return (password.matches("\\w*\\d\\w*"));}@UseCase(id = 48) // description 默认为 no descriptionpublic String encryptPassword(String password) {return new StringBuilder(password).reverse().toString();}@UseCase(id = 49, description = "checkForNewPassword method")public boolean checkForNewPassword(List<String> prevPasswords, String password) {return !prevPasswords.contains(password);}
}
/* 反编译简要结果如下:
D:\workbench_idea\study4vw\thinkinjava\src>javap chapter20.PasswordUtils
Compiled from "PasswordUtils.java"
public class chapter20.PasswordUtils {public chapter20.PasswordUtils();public boolean validatePassword(java.lang.String);public java.lang.String encryptPassword(java.lang.String);public boolean checkForNewPassword(java.util.List<java.lang.String>, java.lang.String);
}
*/

解析注解

/*** 注解解析测试用例*/
public class AnnotationDiyTest {public final static <T> void  f1(Class<T> c1) {for (Method method : c1.getMethods()) { // 获取类定义方法UseCase useCase = method.getAnnotation(UseCase.class); // 获取方法上某个注解if (useCase != null) {System.out.println(useCase.id() + "-" + useCase.description()); // 解析注解}}}public static void main(String[] args) {f1(PasswordUtils.class);}
}
/*
47-validatePassword method
48-no description
49-checkForNewPassword method
*/

【4】自定义注解

UseCase注解有两个方法,方法返回类型有 int,String;此外还有其他返回类型,包括

所有基本类型;
String;
Class
enum;
Annotation;// 注解的成员方法的返回值类型还可以是注解类型
以及以上类型的数组; 

下面定义一个嵌套注解(即注解的方法返回类型是注解类型)

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {int value() default 0;String name() default "";Constraints constraints() default @Constraints();// 嵌套注解
} // /:~
// 定义注解(并定义嵌套注解)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {int value() default 0;String name() default "";// 嵌套注解,因为 Constraints 也是注解类型Constraints constraints() default @Constraints;
} // /:~
// 荔枝-定义注解(并定义嵌套注解)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLDouble {double value() default 0f;// 嵌套注解,因为 Constraints 也是注解类型Constraints constraints() default @Constraints;
}
// 荔枝-定义注解用于生成一个数据库表
@Target(ElementType.TYPE) // 注解作用于哪里(注解的作用对象)
// Applies to classes only
@Retention(RetentionPolicy.RUNTIME) // 注解的作用时间(这里是运行时)
public @interface DBTable {// DBTable 有一个name元素// 这个注解通过使用 value元素 为处理器创建数据库表提供的表名public String value() default "";
} // /:~
// 荔枝-为修饰 javabean域 准备的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {boolean primaryKey() default false; // 主键boolean allowNull() default true; // 允许为空boolean unique() default false; // 唯一键
} // /:~

使用注解创建数据库表对应的javabean

// DBTable 注解作用于类
@DBTable("MEMBER")
public class Member {@SQLString(30) String firstName;@SQLString(value=50, name = "lastName") String lastName;@SQLInteger(name = "age", constraints = @Constraints(primaryKey=true, allowNull=false, unique=true)) Integer age;@SQLString(value = 30 , name = "handle", constraints = @Constraints(primaryKey = true))String handle;static int memberCount;public String getHandle() {return handle;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public String toString() {return handle;}public Integer getAge() {return age;}
} // /:~

使用注解的快捷方式:如果注解中定义了名为value元素(value方法),且在使用注解时,该元素是唯一一个需要复制的元素,那么只需要给出value元素的值即可,无需写键值对形式
@DBTable("MEMBER")-快捷方式 , @DBTable(value="MEMBER")-普通方式


【5】使用apt处理注解

1)问题, 上述代码中,都需要为注解编写处理器以解析注解; 很麻烦;

使用 apt类库方法可以生成注解处理器,apt 是使用源代码生成注解的,无法通过class文件获取类的属性;但 mirror api 可以允许程序员在源代码中查看类属性,如方法,属性;

2)注解

// 抽取注解
@Target(ElementType.TYPE) //
@Retention(RetentionPolicy.SOURCE) // 在源文件起作用
public @interface ExtractInterface {public String value();
} // /:~

【6】小结

java se5仅提供了很少的注解,大多数情况下,需要自定义注解及注解处理器(特别是开发底层框架的时候,需要自定义注解);

javassist 能够用来操作字节码;mirror api 能够用来找出java源代码中的元素 (apt-mirror-api maven repo);

thinking-in-java(20)注解相关推荐

  1. java spring框架 注解_史上最全的java spring注解

    史上最全的java spring注解,没有之一 注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好.不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就 ...

  2. JAVA配置注解方式搭建简单的SpringMVC前后台交互系统

    前面两篇文章介绍了 基于XML方式搭建SpringMVC前后台交互系统的方法,博文链接如下: http://www.cnblogs.com/hunterCecil/p/8252060.html htt ...

  3. java自定义注解为空值_java自定义注解

    1. Java注解(Annotation) Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 注解相关类都包含在java.lang.annot ...

  4. 深入理解Java:注解(Annotation)基本概念、自定义注解、注解解析器

    深入理解Java:注解(Annotation)基本概念 什么是注解(Annotation): Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和着任何元数据(metadat ...

  5. @async注解_史上最全的java spring注解

    史上最全的java spring注解,没有之一 注解是个好东西,但好东西我们也是看见过,整理过,理解过,用过才知道好.不求我们每个都记住,但求保有印象,在需要的时候能提取出来再查找相关资料,平时工作就 ...

  6. Java基于注解和反射导入导出Excel

    代码地址如下: http://www.demodashi.com/demo/11995.html 1. 构建项目 使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包 ...

  7. java path 注解_Java内置系统注解和元注解

    第一节:注解(Annotation)的作用 Annotation(注解)是JDK5.0及以后版本引入的.它的作用是修饰程序元素.什么是程序元素呢?例如:包.类.构造方法.方法.成员变量等. 注解,就是 ...

  8. java自定义注解枚举_java_自定义注解

    1 注解的定义和用途 1.1 官方描述 An annotation is a form of metadata, that can be added to Java source code. Clas ...

  9. 全网最全的JAVA所有版本特性【JAVA 1.0 - JAVA 20】

    闲来想了解下各版本之间的特性,搜索没有最新的特性说明,故想写一份.废话不多说. PS:绝对全网最全最齐,若不是,请私聊我补充,哈哈哈哈! JDK Version 1.0 1996-01-23 Oak( ...

  10. 夯实 Java 基础 - 注解

    夯实 Java 基础 - 注解 不知道大家有没有一种感觉,当你想要了解某个知识点的时候,就会发现好多技术类 APP 或者公众号在推一些关于这个知识点的文章.也许这就是大数据的作用,这也说明总有人比你抢 ...

最新文章

  1. note-在VisualStudio中使用正则表达式
  2. 新手必须掌握的学车技巧-上坡起步
  3. 最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐!
  4. Java使用Springboot集成Es官方推荐(RestHighLevelClient)
  5. 10款你应该了解的开源安全工具
  6. eBPF and IO Visor: The what, how, and what next!
  7. 在线图片转base64工具
  8. 中英文对照 —— 色彩的描述
  9. 在linux缓存里写数据,缓存策略
  10. html字体外颜色轮廓,文字轮廓效果
  11. 信息安全技术国家相关标准一览表
  12. WIN10教育版激活方法
  13. 现在程序员的工资是不是被高估了?
  14. 创业团队:太极图形团队
  15. 使用Spring Environment遇到的问题, 如读取到配置不是自己实际想要的
  16. windows NTFS文件系统手动数据恢复
  17. win10 自带截图工具 SnippingTool
  18. PotPlayer 绿色版下载安装、直播 CCTV
  19. 下载maven私服所有jar包
  20. Android 后台保活,这里有你需要的所有姿势。2019,flutterlistview滚动卡顿

热门文章

  1. P3327 [SDOI2015]约数个数和
  2. CF1270H Number of Components(线段树)
  3. Caddi Programming Contest 2021(AtCoder Beginner Contest 193) 题解
  4. 粉刷木板(ybtoj-单调队列)
  5. P3244-[HNOI2015]落忆枫音【dp】
  6. jzoj4637-大鱼海棠【博弈论】
  7. P4562-[JXOI2018]游戏【数论,组合数学】
  8. jzoj5231-序列问题【分治】
  9. 3、数据库中的字符集和校对集
  10. 对Java的URL类支持的协议进行扩展的方法