在开发过程中总能用到注解,但是从来没有自己定义过注解。最近赋闲在家,研究整理了一番,力求知其然知其所以然。

本文会尝试描述什么是注解,以及通过一个Demo来说明如何在程序中自定义注解。Demo没有实际意义,仅仅只是为了注解而使用注解。

1、什么是注解?

注解是在jdk 1.5开始提供的功能,目前被广泛使用。以下是引用《Java疯狂讲义》第十四章关于注解的描述:

“Annotation其实是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行响应的处理。通过使用Annotation,程序开发人员可以在不改变原有逻辑的情况下,在源文件嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。”

JUnit单元测试就是基于注解的。我认为使用动态代理和注解,自己完全也可以写一个MyJUnit。

2、Demo的实现:

注解文件:

这个文件主要包含了三个部分:

A.注解文件使用@interface来声明。

B.在A外层有元注解声明(注解的注解),主要的作用就是对我们自定义注解的执行范围、时期进声明。下面是注解的注解含义说明:

@Documented:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。

@Target:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上。

@Inherited:指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

@Retention:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。

C.方法名就是参数名,返回值类型就是参数的类型,通过default来设置方法的默认值。

下面是代码:

 package com.array7.annotationTest;

 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; @Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo {
String author() default "array7"; // 作者
String date(); // 日期
double version() default 1.0; // 版本号
String comments(); // 注释
}

然后定义个调用注解的类:

 package com.array7.annotationTest;

 public class AnnotationExample {
/**
* 非静态方法
* @param msg
*/
@MethodInfo(author = "七郎", comments = "方法测试注释:print10", date = "2013-11-29", version = 1.0)
public void print10(Object msg) {
System.out.println(msg);
} /**
* 静态方法
*/
@MethodInfo(author = "七郎", comments = "方法测试注释:print20", date = "2013-11-20", version = 2.0)
public static void print20() {
System.out.println("test");
}
}

最后就是注解解析类(简单起见我将代码写在了main方法里):

 package com.array7.annotationTest;

 import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class AnnotationParsing {
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("com.array7.annotationTest.AnnotationExample"); // 这里可以封装成动态代理类。
// Class clazz = AnnotationParsing.class.getClassLoader().loadClass("com.array7.annotationTest.AnnotationExample"); // 这种方式也OK。
for (Method method : clazz.getMethods()) {
if (method.isAnnotationPresent(MethodInfo.class)) {
for (Annotation anno : method.getAnnotations()) {
System.out.println("Annotation in Method [" + method + "]:" + anno);
MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
if (methodInfo.version() == 1.0) {
method.invoke(clazz.newInstance(), methodInfo.comments());
} else if (methodInfo.version() == 2.0) {
method.invoke(null);
}
}
}
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

程序最后输出:

Annotation in Method [public void com.array7.annotationTest.AnnotationExample.print10(java.lang.Object)]:@com.array7.annotationTest.MethodInfo(author=七郎, version=1.0, comments=方法测试注释, date=2013-11-20)
方法测试注释
Annotation in Method [public static void com.array7.annotationTest.AnnotationExample.print20()]:@com.array7.annotationTest.MethodInfo(author=七郎, version=2.0, comments=方法测试注释, date=2013-11-20)
test

一个从CSDN出逃的人~~

http://blog.csdn.net/array7

Java Annotation自定义注解详解的更多相关文章

  1. java中的注解详解和自定义注解

    一.java中的注解详解 1.什么是注解 用一个词就可以描述注解,那就是元数据,即一种描述数据的数据.所以,可以说注解就是源代码的元数据.比如,下面这段代码: @Override public Str ...

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

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

  3. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  4. Java编程配置思路详解

    Java编程配置思路详解 SpringBoot虽然提供了很多优秀的starter帮助我们快速开发,可实际生产环境的特殊性,我们依然需要对默认整合配置做自定义操作,提高程序的可控性,虽然你配的不一定比官 ...

  5. SpringMVC 常用注解 详解

    SpringMVC 常用注解 详解 SpringMVC 常用注解 1.@RequestMapping                                      路径映射 2.@Requ ...

  6. 【转】@RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解 2014-06-02 11:24 23683人阅读 评论(2) 收藏 举报 目录(?)[+] 引言 ...

  7. Java基础学习总结(24)——Java单元测试之JUnit4详解

    Java单元测试之JUnit4详解 与JUnit3不同,JUnit4通过注解的方式来识别测试方法.目前支持的主要注解有: @BeforeClass 全局只会执行一次,而且是第一个运行 @Before  ...

  8. Spring IoC 公共注解详解

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 什么是公共注解?公共注解就是常见的Java ...

  9. Java版人脸检测详解下篇:编码

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

随机推荐

  1. SQL Server的数据库连接的极限在哪儿?

    在软件设计中,关于多层的设计,有一部份是有关数据库的. 设计上分成这样三层 客户端UI -- 应用服务器 -- 数据库服务器 有个说法是,可以在应用服务器这一层共享使用数据库连接池,从而减轻数据库服务 ...

  2. 高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)

    循环 在javaScript中的四种循环中(for.for-in.while.do-while),只有for-in循环比其它几种明显要慢,另外三种速度区别不大 有一点需要注意的是,javascript ...

  3. matlab注释

    单行注释: 两个'%': 多行注释: A. %{ 若干语句 %} B. 注释: 选中要注释的若干语句, 编辑器菜单Text->Comment, 或者快捷键Ctrl+R 取消注释: 选中要取消注释 ...

  4. apache无法正常启动,80端口被占用的解决方法

    apache无法正常启动,80端口被占用的解决方法 网上的方法: 仔细查看提示: make_sock: could not bind to address 0.0.0.0:80 恍然大悟,计算机上安装 ...

  5. EasyUI学习笔记之panel

    <easyUI panel 属性:> <!--引入easyUI panel 组件 设置宽,高,定义标题(默认在左上角),设置图标iconCls:'icon-ok',引入工具tools ...

  6. Ubuntu下安装了java但启动eclipse报错说没装java

    参考资料:http://blog.csdn.net/happyteafriends/article/details/8290950 一.问题 在Ubuntu下安装了java并在~/.bashrc配置了 ...

  7. Linux下非root用户如何安装软件

    Linux下非root用户如何安装软件 从windows转移到Linux的用户最开始总会有各种不适,因为这种不适最终放弃linux的不在少数.对于这类人只能说可惜,还没有领略到linux的美好就过早放 ...

  8. Sql — CTE公用表表达式和With用法总结

    CTE(Common Table Expression) 公用表表达式,它是在单个语句的执行范围内定义的临时结果集,只在查询期间有效.它可以自引用,也可在同一查询中多次引用,实现了代码段的重复利用. ...

  9. asp.net 中的app_offline.htm的使用

    前段时间,系统升级,由于系统更新发布时间较长,所以必须停掉站点进行更新.导致很多用户都来反馈系统无法访问,还认为站点被黑掉了. 所以经过那件事我们也在思考,如何做到不停机,进行热部署.单机环境下(双机 ...

  10. C#程序

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...