什么是注解?

 注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的。 java注解又叫java标注,java提供了一套机制,使得我们可以对方法、类、参数、包、域以及变量等添加标准(即附上某些信息)。且在以后某个时段通过反射将标注的信息提取出来以供使用。

通过使用Annotation,程序开发人员可以在不改变的原有逻辑的情况下,在源文件嵌入一些补充的信息。

Annotation可以用来修饰类、属性、方法,而且Annotation不影响程序的执行,无论是否使用Annotation代码都可以正常执行。

Annotation分为三种:系统内的Annotation、元注解和自定义Annotation

系统内的Annotation分为:

@Override:只能用在方法之上,表示当前的方法定义将覆盖超类中的方法。
@Deprecated:可以设定在程序里的所有的元素上. 
@SuppressWarnings:暂时把一些警告信息消息关闭.

元注解:

元注解,就是定义注解的注解,也就是说这些元注解是的作用就是专门用来约束其它注解的注解。

元注解主要有四个:
@Target,@Retention,@Documented,@Inherited

@Target

 @Target:表示该注解用于什么地方
@Target(ElementType.TYPE) //接口、类、枚举、注解
@Target(ElementType.FIELD) //字段、枚举的常量
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER) //方法参数
@Target(ElementType.CONSTRUCTOR) //构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) ///包
由以上的源码可以知道,他的elementType 可以有多个,一个注解可以为类的,方法的,字段的等等

@Retention(注解的有效时间)

    @Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

@Documented

 @Document:说明该注解将被包含在javadoc中

@Inherited

 @Inherited:说明子类可以继承父类中的该注解

自定义Annotation:

为什么要自定义Annotation?因为仅仅是系统内的三个注解并不满足我们在实际使用当中的需要。

自定义步骤大致分为两步:
1通过@interface关键字(注意,不是interface,是@interace)声明注解名称,以及注解的成员属性或者叫做注解的参数。
2使用java内置的四个元注解对这个自定义标注的功能和范围进行一些限制。
 
一个简单的实例:
 
自定义一个类级别的标注Description
package lighter.javaeye.com;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.TYPE)//这个标注应用于类
@Retention(RetentionPolicy.RUNTIME)//标注会一直保留到运行时
@Documented//将此注解包含在javadoc中
public @interface Description {
String value();
}

再定义个方法级别的注解Name

package lighter.javaeye.com;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; //注意这里的@Target与@Description里的不同,参数成员也不同
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
String originate();
String community();
}

然后使用以上两个注解

package lighter.javaeye.com;

@Description(value="javaeye,做最棒的软件开发交流社区")
public class JavaEyer {
@Name(originate="创始人:robbin",community="javaEye")
public String getName()
{
return null;
} @Name(originate="创始人:江南白衣",community="springside")
public String getName2()
{
return "借用两位的id一用,写这一个例子,请见谅!";
}
}

说明:其中标注“@Description(value="javaeye,做最棒的软件开发交流社区")”,可以写成“@Description("javaeye,做最棒的软件开发交流社区") ”,结果也是一样的。因为Description标注定义的时候其参数(或者说属性)为value。而value比较特殊,它在被指定参数的时候可以不用显示的写出来。当然如果定义的时候参数名不是value而是其它的比如des,那么使用注解的时候,必须显示写出参数名,然后再赋值:@Description(Des=”xxx”)

提取出注解的信息

package lighter.javaeye.com;

 import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set; public class TestAnnotation {
/**
* author lighter
* 说明:具体关天Annotation的API的用法请参见javaDoc文档
*/
public static void main(String[] args) throws Exception {
String CLASS_NAME = "lighter.javaeye.com.JavaEyer";
Class test = Class.forName(CLASS_NAME);
Method[] method = test.getMethods();
boolean flag = test.isAnnotationPresent(Description.class);
if(flag)
{
Description des = (Description)test.getAnnotation(Description.class);
System.out.println("描述:"+des.value());
System.out.println("-----------------");
} //把JavaEyer这一类有利用到@Name的全部方法保存到Set中去
Set<Method> set = new HashSet<Method>();
for(int i=0;i<method.length;i++)
{
boolean otherFlag = method[i].isAnnotationPresent(Name.class);
if(otherFlag) set.add(method[i]);
}
for(Method m: set)
{
Name name = m.getAnnotation(Name.class);
System.out.println(name.originate());
System.out.println("创建的社区:"+name.community());
}
}
}
注意事项:
所有的Annotation会自动继承java.lang.annotation这一个接口,所以不能再去继承别的类或是接口.

 最重要的一点,Annotation类型里面的参数该怎么设定:

 第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型.

 第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String。
 
 
注解经常和反射、枚举一同使用,下面贴上一些枚举和自定义时设置默认值得代码:
public enum name {
xml, zml, cml;
} public @interface mytest {
public name n() default name.zml;
} @mytest(n = name.cml)
class demo{ }

本文大量参考了文章:http://wanqiufeng.blog.51cto.com/409430/458883

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引入的 概念 ...

随机推荐

  1. openstack api

    1,Identity service generates authentication tokens that permit access to the openstack service REST ...

  2. python 定义函数

    在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 我们以自定义一个求绝对值的my_abs函数 ...

  3. 【3D研发笔记】之【数学相关】(一):坐标系

    现在开始学习3D基础相关的知识,本系列的数学相关笔记是基于阅读书籍<3D数学基础:图形与游戏开发>而来,实现代码使用AS3,项目地址是:https://github.com/hammerc ...

  4. TCP建立连接的3次握手和关闭连接的4次挥手

    #.3次握手过程状态 第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+ ...

  5. Android设计模式系列-组合模式

    Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用.在android UI设计,几乎所有的widget和布局类都依靠这两个类.组合模式,Compos ...

  6. 【20】宁以pass-by-reference-to-const替换pass-by-value

    1.首先理解需求,被调用方法修改了形参,如果期望在主调方法中的实参也发生变化,必须使用pass-by-reference.因为C++缺省情况下(继承C方式),以by-value传递对象,在被调方法中修 ...

  7. BZOJ 2150: 部落战争 最大流

    2150: 部落战争 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php? ...

  8. c# 调用 c++写的DLL

    http://www.cnblogs.com/MarsPanda/archive/2012/09/03/2668522.html 解决办法 安装 vcredist 运行库 或者用VC6.0编写DLL ...

  9. Android模拟器操作快捷键

    你可以通过模拟器的启动选项和控制台命令来控制模拟环境的行为和特性.一旦模拟器启动,你就可以通过键盘和鼠标来“按” 模拟器的按键,从而操作模拟器.下面的表格总结了模拟器按键可键盘按键之间的映射关系. 模 ...

  10. c++ 怎样获取系统时间

    c++ 怎样获取系统时间 2008-04-28 15:34 //方案— 长处:仅使用C标准库:缺点:仅仅能精确到秒级 #include <time.h> #include <stdi ...