一、背景

  最近在自己搞一个项目时,遇到可需要开发自定义注解的需求,对于没有怎么关注这些java新特性的来说,比较尴尬,索性就拿出一些时间,来进行研究下自定义注解开发的步骤以及使用方式。今天在这里记下,方便以后学习复习以及分享给有需要的小伙伴们~

二、注解基本概念

  什么是注解?

    注解就是某种注解类型的一个实例,我们可以用它在某个类上进行标注,这样编译器在编译我们的文件时,会根据我们自己设定的方法来编译类。

  注解的分类有哪些?

  

由上图可知:注解共分为:标记注解、标准元注解、一般注解三类。

注:Deprecated注解,除了多个删除线,并没有什么拦截功能。

  标准元注解详解

    标准元注解是自定义注解的注解,主要包含4个,都位于java.lang.annotation包中,我们创建自定义注解时会用到4个标准元注解。它们的名称以及含义如下:

      1. @Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。是一个标记注解,没有成员。

      2. @Inherited:是一个标记注解阐述了某个被标注的类型是被继承的。使用了@Inherited修饰的注解类型被用于一个class时该class的子类也有了该注解。

      3. @Retention:定义了该注解的生命周期:某些注解仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为注解与class在使用上是被分离的)。使用这个元注解可以对自定义注解的“生命周期”进行限制。

      生命周期策略枚举

      RetentionPolicy.RUNTIME 注解会在class字节码文件中存在,在运行时可以通过反射获取到。

      RetentionPolicy.CLASS 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。

      RetentionPolicy.SOURCE 注解仅存在于源码中,在class字节码文件中不包含。

      4. @Target:说明了注解所修饰的对象范围:注解可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。

       修饰范围枚举

        ElementType.CONSTRUCTOR  作用于构造器
        ElementType.FIELD  作用于域/属性
        ElementType.LOCAL_VARIABLE  用于描述局部变量
        ElementType.METHOD  作用于方法
        ElementType.PACKAGE   用于描述包
        ElementType.PARAMETER   用于描述参数
        ElementType.TYPE   用于描述类、接口(包括注解类型) 或enum声明,最常用

三、开发自定义注解demo

1.开发自定义类注解

  1. package com.hafiz.zhang.annotation;
  2.  
  3. import java.lang.annotation.Documented;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8.  
  9. /**
  10. * @author hafiz.Zhang
  11. * @Date 2016年5月18日 下午1:58:11
  12. * @Description 自定义类注解
  13. */
  14. @Documented //定义可以被文档工具文档化
  15. @Retention(RetentionPolicy.RUNTIME)//声明周期为runtime,运行时可以通过反射拿到
  16. @Target(ElementType.TYPE)//注解修饰范围为类、接口、枚举
  17. public @interface ClassAnnotation {
  18. public String name() default "defaultService";
  19. public String version() default "1.1.0";
  20. }

2.自定义方法注解

  1. package com.hafiz.zhang.annotation;
  2.  
  3. import java.lang.annotation.Documented;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8.  
  9. import com.hafiz.zhang.annotation.en.MethodTypeEnum;
  10.  
  11. /**
  12. * @author hafiz.Zhang
  13. * @Date 2016年5月18日 下午1:58:26
  14. * @Description 自定义方法注解
  15. */
  16. @Documented
  17. @Retention(RetentionPolicy.RUNTIME)
  18. @Target(ElementType.METHOD)
  19. public @interface MethodAnnotation {
  20. public String name() default "defaultName";
  21. public MethodTypeEnum type() default MethodTypeEnum.TYPE1;
  22. }

3.自定义域注解

  1. package com.hafiz.zhang.annotation;
  2.  
  3. import java.lang.annotation.Documented;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8.  
  9. /**
  10. * @author hafiz.Zhang
  11. * @Date 2016年5月18日 下午1:58:37
  12. * @Description 自定义域注解
  13. */
  14. @Documented
  15. @Target(ElementType.FIELD)
  16. @Retention(RetentionPolicy.RUNTIME)
  17. public @interface FieldAnnotation {
  18. public String name() default "defaultName";
  19. public String value() default "defaultValue";
  20.  
  21. }

4.方法类型枚举类

  1. package com.hafiz.zhang.annotation.en;
  2.  
  3. /**
  4. * @author hafiz.Zhang
  5. * @Date 2016年5月18日 下午1:59:02
  6. * @Description 方法类型枚举类
  7. */
  8. public enum MethodTypeEnum {
  9. TYPE1,TYPE2
  10. }

5.测试注解Bean

  1. package com.hafiz.zhang.annotation.bean;
  2.  
  3. import com.hafiz.zhang.annotation.ClassAnnotation;
  4. import com.hafiz.zhang.annotation.FieldAnnotation;
  5. import com.hafiz.zhang.annotation.MethodAnnotation;
  6. import com.hafiz.zhang.annotation.en.MethodTypeEnum;
  7.  
  8. /**
  9. * @author hafiz.Zhang
  10. * @Date 2016年5月18日 上午11:59:37
  11. * @Description 测试使用的bean
  12. */
  13. @ClassAnnotation(name="personBean", version="1.2.1")
  14. public class Person {
  15. @FieldAnnotation(name="description", value="This is my personal annotation")
  16. private String description;
  17.  
  18. public String getDescription() {
  19. return description;
  20. }
  21.  
  22. public void setDescription(String description) {
  23. this.description = description;
  24. }
  25. @MethodAnnotation(name="sayHello", type = MethodTypeEnum.TYPE2)
  26. public void sayHello() {
  27. System.out.println("Hello Annotation!");
  28. }
  29. }

6.自定义类注解测试类

  1. package com.hafiz.zhang.annotation.test;
  2.  
  3. import com.hafiz.zhang.annotation.ClassAnnotation;
  4. import com.hafiz.zhang.annotation.bean.Person;
  5.  
  6. /**
  7. * @author hafiz.Zhang
  8. * @Date 2016年5月18日 上午11:56:34
  9. * @Description 测试类注解
  10. */
  11. public class TestClassAnnotation {
  12.  
  13. private static Person person = new Person();
  14.  
  15. public static void main(String[] args) {
  16. Class<?> clazz = person.getClass();
  17. //因为注解是作用于类上面的,所以可以通过isAnnotationPresent来判断是否是一个具有指定注解的类
  18. if(clazz.isAnnotationPresent(ClassAnnotation.class)) {
  19. System.out.println("This is a class with annotation ClassAnnotation!");
  20. //通过getAnnotation可以获取注解对象
  21. ClassAnnotation annotation = clazz.getAnnotation(ClassAnnotation.class);
  22. if(null != annotation) {
  23. System.out.println("BeanName = " + annotation.name());
  24. System.out.println("BeanVersion = " + annotation.version());
  25. }else{
  26. System.out.println("the annotation that we get is null");
  27. }
  28. }else{
  29. System.out.println("This is not the class that with ClassAnnotation");
  30. }
  31. }
  32. }

运行结果:

7.自定义方法注解测试类

  1. package com.hafiz.zhang.annotation.test;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import com.hafiz.zhang.annotation.MethodAnnotation;
  6. import com.hafiz.zhang.annotation.bean.Person;
  7.  
  8. /**
  9. * @author hafiz.Zhang
  10. * @Date 2016年5月18日 下午12:11:11
  11. * @Description 测试方法注解
  12. */
  13. public class TestMethodAnnotation {
  14.  
  15. private static Person person = new Person();
  16.  
  17. public static void main(String[] args) throws Exception {
  18. Class<?> clazz = person.getClass();
  19. //因为是注解到method上的,所以首先要获取这个方法
  20. Method method = clazz.getDeclaredMethod("sayHello");
  21. if(method.isAnnotationPresent(MethodAnnotation.class)) {
  22. System.out.println("===This is a method with a annotation:MethodAnnotation===");
  23. //通过getAnnotation可以获取注解对象
  24. MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);
  25. if(null != annotation) {
  26. System.out.println("MethodName = " + annotation.name());
  27. System.out.println("MethodType = " + annotation.type());
  28. }else{
  29. System.out.println("the annotation that we get is null");
  30. }
  31. }else{
  32. System.out.println("This is not the class that with MethodAnnotation");
  33. }
  34. }
  35. }

运行结果:

8.自定义域注解测试类

  1. package com.hafiz.zhang.annotation.test;
  2.  
  3. import java.lang.reflect.Field;
  4.  
  5. import com.hafiz.zhang.annotation.FieldAnnotation;
  6. import com.hafiz.zhang.annotation.bean.Person;
  7.  
  8. /**
  9. * @author hafiz.Zhang
  10. * @Date 2016年5月18日 下午12:17:49
  11. * @Description 测试域注解
  12. */
  13. public class TestFieldAnnotation {
  14.  
  15. private static Person person = new Person();
  16.  
  17. public static void main(String[] args) throws Exception {
  18. Class<?> clazz = person.getClass();
  19. //因为是注解到Field上的,所以首先要获取这个字段
  20. Field field = clazz.getDeclaredField("description");
  21. //判断这个Field上是否有这个注解
  22. if(field.isAnnotationPresent(FieldAnnotation.class)) {
  23. System.out.println("===This is a field with annotation:FieldAnnotation!===");
  24. //如果有这个注解,则获取注解类
  25. FieldAnnotation annotation = field.getAnnotation(FieldAnnotation.class);
  26. if(null != annotation){
  27. System.out.println("before set the value is:" + person.getDescription());
  28. //通过反射给私有变量赋值
  29. field.setAccessible(true);
  30. field.set(person, annotation.value());
  31. System.out.println("after set the value is:" + person.getDescription());
  32. }else{
  33. System.out.println("the annotation that we get is null");
  34. }
  35. }else{
  36. System.out.println("This is not the class that with FieldAnnotation");
  37. }
  38. }
  39. }

运行结果:

附:demo项目结构图

以上就是本人对自定义注解开发的理解以及开发测试了,如有错误希望大家能够批评指正!

Java自定义注解开发的更多相关文章

  1. Java实现自定义注解开发

    Java实现自定义注解开发 一直都对注解开发挺好奇的,最近终于有时间自己实践了一把,记录一下 万一后期会用到呢 哈哈哈 首先我们了解一下自定义注解的标准示例,注解类使用 @interface 关键字修 ...

  2. java自定义注解注解方法、类、属性等等【转】

    http://anole1982.iteye.com/blog/1450421 http://www.open-open.com/doc/view/51fe76de67214563b20b385320 ...

  3. java自定义注解学习(二)_注解详解

    上篇文章,我们简单的实现了一个自定义注解,相信大家对自定义注解有了个简单的认识,这篇,这样介绍下注解中的元注解和内置注解 整体图示 内置注解 @Override 重写覆盖 这个注解大家应该经常用到,主 ...

  4. JAVA自定义注解 ------ Annotation

    日常开发工作中,合理的使用注解,可以简化代码编写以及使代码结构更加简单,下面记录下,JAVA自定义注解的开发过程. 定义注解声明类. 编写注解处理器(主要起作用部分). 使用注解. 相关知识点介绍, ...

  5. java自定义注解类

    一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...

  6. java自定义注解实现前后台参数校验

    2016.07.26 qq:992591601,欢迎交流 首先介绍些基本概念: Annotations(also known as metadata)provide a formalized way ...

  7. java自定义注解知识实例及SSH框架下,拦截器中无法获得java注解属性值的问题

    一.java自定义注解相关知识 注解这东西是java语言本身就带有的功能特点,于struts,hibernate,spring这三个框架无关.使用得当特别方便.基于注解的xml文件配置方式也受到人们的 ...

  8. Java自定义注解的实现

    Java自定义注解的实现,总共三步(eg.@RandomlyThrowsException): 1.首先编写一个自定义注解@RandomlyThrowsException package com.gi ...

  9. Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性)

    Java自定义注解源码+原理解释(使用Java自定义注解校验bean传入参数合法性) 前言:由于前段时间忙于写接口,在接口中需要做很多的参数校验,本着简洁.高效的原则,便写了这个小工具供自己使用(内容 ...

随机推荐

  1. poj 3744 Scout YYF I(概率dp,矩阵优化)

    Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5020   Accepted: 1355 Descr ...

  2. html5开发制作,漂亮html5模板欣赏,H5网站建设

    html5是什么? HTML5 是下一代的 HTML(超文本标记语言,网页的组成部分),HTML5是web开发世界的一次重大的改变,能适配pc.手机等各终端,跨平台性能极强,移动互联网是未来的趋势,h ...

  3. FineUI第十八天---表格之事件的处理

    表格之事件的处理: 1.事件参数: GridPageEventArgs:表格分页事件参数,对应onPageIndexChange事件. NewPageIndex:新页面的索引 GridSortEven ...

  4. 【转】phpcms-v9中关于模型的理解

    PHPCMS v9 模型概念 一.什么是模型? 模型是系统知识的抽象表示.我们不能仅仅通过语言来描述一个系统,也不能仅仅通过记忆来记录关于系统的知识.知识是通过某种媒介来表达的,这种媒介所表达的内容就 ...

  5. HDU1102--最小生成树

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. BZOJ3224——Tyvj 1728 普通平衡树

    1.题目大意:数据结构题,是treap,全都是treap比较基本的操作 2.分析:没啥思考的 #include <cstdio> #include <cstdlib> #inc ...

  7. 修复 VirtualBox 下 Ubuntu 14.10 屏幕分辨率问题

    在 Windows 7 下使用 VirtualBox 安装了一个 Ubuntu 14.10 后,碰到了一个 640×480 屏幕分辨率的问题. 在 ‘Display Settings' 设置界面的 ‘ ...

  8. 我对自己提的几个关于cocos2dx的几个问题

    1.友元函数的定义: 2.运算符重载: 3.内存关机机制: 4.动作侦听: 5.单点触摸: 6.触摸目标判断: 7.事件传递: 8.多点触摸: 9.加速传感器: 10.物理按键交互: 11.绘图API ...

  9. 十进制转为N进制

    昨天笔试遇到的题,如果是正数,不断以余数做除法即可: void convert(int num, int N, vector<char>& data) { int number = ...

  10. windows下php,redis配置

    在windows环境下搭建redis是一般是为了测试,官方redis并没有给windows版redis但是微软有. windows版下载地址:https://github.com/MSOpenTech ...