Annotation不算常用的技术,早前用它写了一些玩意儿,过了一年又忘干净了,今天写点东西记下来,以备再忘之需。

java.lang.annotation,接口 Annotation。对于Annotation,是Java5的新特性,JDK5引入了Metedata(元数据)很容易的就能够调用Annotations。Annotations提供一些本来不属于程序的数据,比如:一段代码的作者或者告诉编译器禁止一些特殊的错误。An annotation 对代码的执行没有什么影响。Annotations使用@annotation的形式应用于代码:类(class),属性(attribute),方法(method)等等。一个Annotation出现在上面提到的开始位置,而且一般只有一行,也可以包含有任意的参数。

——————百度百科

Annotation是什么,上面说得很清楚了,下面重点说,它怎么写,和有什么用。

一、Annotation的基本写法

/**
* @author caiyu
* @date 2014-1-21
*/ @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSchemaConfig {
String type() default "get";
    String value();
}

1、DataSchemaConfig为Annotation的名称

2、 @Retention 表示该Annotation的保留级别

分别以下三种:

RetentionPolicy.RUNTIME

会记录在CLASS里,同时会在运行时保留该注解,以使其可以被反射读取。

RetentionPolicy.SOURCE

只存在于源码里,会被编译器抛弃

RetentionPolicy.CLASS

会被编译器记录在CLASS文件中,但虚拟机不会在运行时保留它。该选项是默认选项

3、@Target表示该Annotation的影响范围,如下所示:

package java.lang.annotation;

/**
* A program element type. The constants of this enumerated type
* provide a simple classification of the declared elements in a
* Java program.
*
* <p>These constants are used with the {@link Target} meta-annotation type
* to specify where it is legal to use an annotation type.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE, /** Field declaration (includes enum constants) */
FIELD, /** Method declaration */
METHOD, /** Parameter declaration */
PARAMETER, /** Constructor declaration */
CONSTRUCTOR, /** Local variable declaration */
LOCAL_VARIABLE, /** Annotation type declaration */
ANNOTATION_TYPE, /** Package declaration */
PACKAGE
}

4、内容组织形式

String type() default "get";

这段声明里,String为成员类型,type为成员名称(必须写上括号),default "get"表示缺省指为"get"

5、使用见如下示例代码

/**
* @author caiyu
* @date 2014-1-22
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DataType {
public String value() default "map";
} @DataType(value = "bean")
public class MapModel {
private Map<String, Object> o = new HashMap<String, Object>(); @GET
public Object get(String key) {
return o.get(key);
} @PUT
public void put(String key, Object value) {
o.put(key, value);
}
}
DataType 这个Annotation被声明为Runtime以及TYPE,所以它可以被用于注解MapModel这个类。
括号里的value="bean",则是为其value赋值1,同时由于value是个特殊成员,可以写作
@DataType("bean")

如果写作

@DataType

则value会使用默认值"map"

6、数组形式的成员类型的使用

 把上面的内容改成下面的格式:

String[] value() default "map";

之前的这种写法@DataType("bean")仍然是合法的

同时可以写作@DataType({"map","bean"})

 二、Annotaion的用途

在介绍@Retention的时候,其实已经说明了Annotation的三种类型了,SOURCE和CLASS类型使用很少,如果你不是需要自己写一个Java Compiler或者Editor,基本用不上。

这里重点说说RUNTIME类型。

我们知道,RUNTIME会被保存在CLASS文件中,而且其中记录的信息可以通过反射来获取到,于是可以利用这点实现一些方便的配置(比如Spring和Hibernate就是利用这点)。

来看看一个MapModel类:

@DataType
public class MapModel {
private Map<String, Object> o = new HashMap<String, Object>(); @get
public Object getProperty(String key) {
return o.get(key);
} @put
public void putProperty(String key, Object value) {
o.put(key, value);
} public String toString() {
return o.toString();
}
}

可以看到,MapModel标记了三个注解,分别是DataType和get、put

下面的代码,是用来把该Model和org.dom4j.Element相互转换的,注意只能参考,并不完整:

/**
* 序列化注解类型
*
* @param content
* @param schema
* @return
*/
private Element serialMapType(Object content, IDataSchema<?> schema) {
DataType type = schema.getType().getAnnotation(DataType.class);
if (type != null && type.value() == DataTypeValue.MAP) {
Element root = DocumentFactory.getInstance().createElement(
schema.getName()); Method getMethod = extraMethodByAnnotation(schema.getType(),
get.class);
if (getMethod == null)
throw new InvalidAnnotationConfigException(
"Invalid annotation class: "
+ schema.getType().getName());
try {
for (Entry<String, IDataSchema<?>> field : schema
.getFieldEntrySet()) {
Object o = getMethod.invoke(content, field.getValue()
.getId());
Element e = save(o, field.getValue());
root.add(e);
}
return root;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
throw new InvalidAnnotationConfigException(
"Invalid put method : " + getMethod.getName());
} catch (InvocationTargetException e) {
e.printStackTrace();
} } return null;
} /**
* 反序列化注解类型数据
*
* @param persistentTarget
* @param schema
* @return
*/
private Object deserialMapType(Element persistentTarget,
IDataSchema<?> schema) {
Object instance = null;
DataType type = schema.getType().getAnnotation(DataType.class);
if (type != null && type.value() == DataTypeValue.MAP) {
Method putMethod = extraMethodByAnnotation(schema.getType(),
put.class);
if (putMethod == null)
throw new InvalidAnnotationConfigException(
"Invalid annotation class: "
+ schema.getType().getName());
try {
instance = schema.getType().newInstance();
for (Entry<String, IDataSchema<?>> field : schema
.getFieldEntrySet()) {
Element e = persistentTarget.element(field.getValue()
.getName());
Object v = load(e, field.getValue());
putMethod.invoke(instance, new Object[] {
field.getValue().getId(), v });
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
throw new InvalidAnnotationConfigException(
"Invalid put method : " + putMethod.getName());
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return instance;
}
    /**
* 抽取含有指定注解的方法
*
* @param type
* @param annotationClass
* @return
*/
private Method extraMethodByAnnotation(Class<?> type,
Class<? extends Annotation> annotationClass) {
for (Method method : type.getDeclaredMethods()) {
Annotation t = method.getAnnotation(annotationClass);
if (t != null) {
return method;
} }
return null;
}

Java学习:Annotation注解的更多相关文章

  1. Java学习:注解,反射,动态编译

    狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解  什么是注解 ? Annotat ...

  2. Java学习之注解篇

    Java学习之注解篇 0x00 前言 续上篇文章,这篇文章就来写一下注解的相关内容. 0x01 注解概述 Java注解(Annotation)又称Java标注,是JDK5.0约会的一种注释机制. 和J ...

  3. 对Java的annotation(注解)的认识

    什么是java的annotation(注解) ? 注解的定义(annootation): public @interface TestAnnotation { } 上面的这种形式,便定义了注解是如何定 ...

  4. Java学习之注解Annotation实现原理

    前言: 最近学习了EventBus.BufferKinfe.GreenDao.Retrofit 等优秀开源框架,它们新版本无一另外的都使用到了注解的方式,我们使用在使用的时候也尝到不少好处,基于这种想 ...

  5. 0035 Java学习笔记-注解

    什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...

  6. java EE中的hello1.java及Annotation(注解)

    一.Annotation(注解) 注解(Annotation)很重要,未来的开发模式都需要注解,注解是java.lang.annotation包,Annotation是从java5引入的,它提供一些不 ...

  7. Java学习:注解简介

    JAVA 注解的基本原理 以前,『XML』是各大框架的青睐者,它以松耦合的方式完成了框架中几乎所有的配置,但是随着项目越来越庞大,『XML』的内容也越来越复杂,维护成本变高. 于是就有人提出来一种标记 ...

  8. Java之Annotation(注解)——注解处理器

    如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处 ...

  9. java学习之注解

    0x00前言 1.注解是什么: (1)可以叫做注释类型,注解是一种引用数据类型,编译后也是生成class文件 (2)提供信息给编译器: 编译器可以利用注解来探测错误和警告信息 比如 @Override ...

  10. Java学习之==>注解

    一.概述 关于注解,首先引入官方文档的一句话:Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.接下我将从注解的定义. ...

随机推荐

  1. 【如何快速的开发一个完整的iOS直播app】(采集篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,首先需要采集主 ...

  2. My安卓知识4--Media Player called in state 0

    //根据被传递的歌曲名称,选择播放的歌曲    public void playByName(String name){        mp = new MediaPlayer();        t ...

  3. Unix权限管理

    // */ // ]]> Unix权限管理 Table of Contents 1 Unix权限管理 2 进程权限 3 文件权限 4 进程对文件的存取访问的权限校验过程 1 Unix权限管理 权 ...

  4. android开发学习笔记000

    使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个 ...

  5. JDK、JRE、JVM三者间的关系

    JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE.Java工具和Java基础类库.Java Runtime Enviro ...

  6. aa2

    option = { series : [ { name: 'Map', type: 'map', mapLocation: { x : 'left', y : 'top', height : 500 ...

  7. Linux中的工作管理(Job Control )

    以前使用Linux老是会不小心按下Ctrl + z,然后就出现看不懂的情况,以为程序突然就没了,今天专门研究了下Linux下的几个快捷键和工作管理. 其中找到一篇很不错的文章,大部分是里面转载的. 原 ...

  8. [PL/SQL] 如何规避异常ORA-01403

    如果mytable表中不存在 ID = 123 的数据,那么 SELECT Flag INTO flag FROM mytable WHERE ID = 123 将抛出异常ORA-01403 SELE ...

  9. 【Git】简单地使用github当做远程共享仓库

    简单地使用github当做远程共享仓库 1.进入各自的github,选取一个人的github作为总的远程共享仓库,其余成员每次修改完项目后pull request请求合并自己的修改内容. 2.其余开发 ...

  10. Eclipse创建Android模拟器创建选项解释