注解在JAVA中,尤其是一些ORM框架(如Hibernate等)中是比较常用的一种机制。

  注解是JAVA 1.5之后引入的新功能,正确来说是反射的一部分,没有反射,注解也就无法正常使用。注解可以理解成一种遵循特定规范的标记,也可以理解成是一种额外信息的载体。

  例如,在Hibernate的使用中,我们需要从JAVA类中映射属性到数据表中的字段,但不同JAVA中主键属性的名称不一致,有的叫“id”,有的叫“_id”,甚至有的叫“userid”。此时,注解的作用就展现出来了,Hibernate为我们提供了一个“@Id”的注解,我们通过在一个JAVA类的某个属性上标注这个注解,就可以指定这个属性为主键,而不需要关心这个属性的名字。

  当然,注解的作用不止于此,下面我们会详细的介绍注解的一些常用知识。


1、元注解

  上面提到过,JAVA为我们提供了四种基础的元注解,其种类和简介如下:

  • @Target:说明了Annotation所修饰的对象范围;
  • @Retention:说明了该Annotation所保留的时间长短;
  • @Documented:被标注的元素可以作为程序的公共API而被文档化;
  • @Inherited:说明该Annotation同样适用与这个类的子类。

(1)@Target

  Target说明了这个注解所修饰的对象范围,这个范围可以有以下几种选择:

  1. ElementType.CONSTRUCTOR:用于描述构造器;
  2. ElementType.FIELD:用于描述域;
  3. ElementType.LOCAL_VARIABLE:用于描述局部变量;
  4. ElementType.METHOD:用于描述方法;
  5. ElementType.PACKAGE:用于描述包;
  6. ElementType.PARAMETER:用于描述参数;
  7. ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明。

  也就是说,@Target中指定的是哪个值,这个注解就只能作用在哪个作用域上,如 @Target(ElementType.FIELD) 说明这个注解只能作用于属性上。

(2)@Retention

  Retention说明了这个注解所保留的时间长短,可以有以下几种选择:

  1. RetentionPolicy.SOURCE:在源文件中有效(即源文件保留);
  2. RetentionPolicy.CLASS:在class文件中有效(即class保留);
  3. RetentionPolicy.RUNTIME:在运行时有效(即运行时保留)。

  如果使用SOURCE,则这些注解会被编译器丢弃;如果使用CLASS,则这些注解可能会被虚拟机忽略;而当时用RUNTIME时,则这些注解在class文件被装载时被读取。因此,我们通常都是使用 @Retention(RetentionPolicy.RUNTIME) 。

(3)@Documented

  当使用@Documented注解时,表示被标注的元素可以作为程序的公共API而被文档化,即如果使用javadoc等工具生成文档,则这些注解将被写入文档中。

  @Documented注解中没有参数。

(4)@Inherited

  如果将@Inherited注解到某个类上,则这个类的子类会自动继承此注解,否则的话,子类不会继承此注解。

  这里需要注意的是,@Inherited注解只有注解在类上时才有效,对方法、属性等无效。

  @Inherited注解中没有参数。


2、自定义注解

  自定义注解的格式如下所示:

public @interface 注解名
{
定义体
}

  我们除了可以在注解类上添加元注解外,还可以在定义体中自定义注解参数及其默认值。定义注解参数就像在接口中定义方法一样,具体代码如下:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String stringArg() default "";
public int intArg() default -1;
public boolean boolArg() default false;
}

  下面列举出注解参数可支持的数据类型:

  1. 所有基本数据类型(int、float、boolean、byte、double、char、long、short);
  2. String类型;
  3. Class类型;
  4. enum类型;
  5. Annotation类型;
  6. 以上所有类型的数组。

  定义了注解参数之后,我们就可以像下面代码这样使用这个注解:

public class MyBean {
@MyAnnotation(stringArg="aa", intArg=2, boolArg=true)
private int id;
// ......
}

  定义注解参数需要注意的事项如下:

  (1)只用使用public或默认(default)这两个访问权限修饰;

  (2)需要注意注解参数的数据类型(详见上面的类型范围);

  (3)如果只有一个参数成员,最好把参数名设置为value,如 String value(); ,这样就可以通过 @MyAnnotation("value的值") 来注解,而不需要在参数前面加参数名的引用。


3、注解使用案例

  下面是一个自定义注解的案例,代码如下所示:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
public String stringArg() default "";
public int intArg() default -1;
public boolean boolArg() default false;
}

  接下来看一下注解在类中的使用,代码如下所示:

public class MyBean {
@MyAnnotation(stringArg="aa", intArg=2, boolArg=true)
private int id;
// ......
}

  最后来看一下如何使用反射获取注解的内容,代码如下所示:

public class AnnotationHelper {
private void convertDataToNodes(MyBean bean) throws IllegalAccessException {
Clsss cls = bean.getClass();
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
MyAnnotation ma = field.getAnnotation(MyAnnotation.class);
if (ma != null) {
field.setAccessible(true);
int id = field.getInt(bean); // 获取到被标注属性的值
String stringArg = ma.stringArg(); // 获取到注解中的某个属性的值
int intArg = ma.intArg();
boolean boolArg = ma.boolArg();
// ......
}
}
}
}

  以上就是对JAVA注解的简单介绍,希望对大家有帮助~~

【JAVA - 基础】之Annotation注解浅析的更多相关文章

  1. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  2. Java基础教程:注解

    Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...

  3. Java基础教程(16)--注解

    一.注解基础知识 1.注解的格式   最简单的注解就像下面这样: @Entity   @符号指示编译器其后面的内容是注解.在下面的例子中,注解的名称为Override: @Override void ...

  4. java基础(反射,注解,多线程,juc)

    JAVA基础 java反射 class对象 三种方式获取class加载时对象 1.class.forName("全类名"):将字节码文件加载进内存,返回class对象 2.类名.c ...

  5. 【Java基础】Annotation 的本质和自定义实现

    Java 中注解的实现原理 一.引言 在 Java5 之前,利用 xml 进行配置是各大框架的常规操作,这种方式可以实现松耦合并完成框架中几乎所有需要的配置,但随着项目的扩展,xml 文件本身的内容将 ...

  6. Java基础(五) final关键字浅析

    前面在讲解String时提到了final关键字,本文将对final关键字进行解析. static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提 ...

  7. Java学习:Annotation注解

    Annotation不算常用的技术,早前用它写了一些玩意儿,过了一年又忘干净了,今天写点东西记下来,以备再忘之需. java.lang.annotation,接口 Annotation.对于Annot ...

  8. 一起来看一下Java中的Annotation注解

    目录: 一. 什么是Annotation 二. Annotation的作用 2.1 编译器使用到的注解 2.2 .class文件使用到的注解 2.3 运行期读取的注解 三. 定义Annotation ...

  9. Java 基础篇之注解

    注解 注解,其实是代码里的特殊标记,这些标记可以在编译.类加载.运行时被读取,并执行相应的处理.通过使用注解,可以在不改变原有逻辑的情况下,在源文件中嵌入补充一些信息. Annotation 提供了一 ...

随机推荐

  1. [转载]C#实现POST提交方式

    网页自动登录和提交POST信息的核心就是分析网页的源代码(HTML),在C#中,可以用来提取网页HTML的组件比较多,常用的用WebBrowser.WebClient.HttpWebRequest这三 ...

  2. 理解 Android 本地数据存储 API

    利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸 ...

  3. 练习PYTHON之EVENTLET

    以下是重点,要会运用: eventlet是一个用来处理和网络相关的python库函数,而且可以通过协程来实现并发,在eventlet里,把“协程”叫做 greenthread(绿色线程).所谓并发,就 ...

  4. Mysql的列索引和多列索引(联合索引)

    转自:http://blog.chinaunix.net/uid-29305839-id-4257512.html 创建一个多列索引:CREATE TABLE test (      id       ...

  5. MongoDB实战指南(二):索引与查询优化

    数据库保存记录的机制是建立在文件系统上的,索引也是以文件的形式存储在磁盘上,在数据库中用到最多的索引结构就是B树.尽管索引在数据库领域是不可缺少的,但是对一个表建立过多的索引会带来一些问题,索引的建立 ...

  6. Handler 接收Parcelable ArrayList时返回空的错误

    遇到一个问题,从handler 接收的Parcelable ArrayList返回空,调试发现这个arraylist生成的时候是有值的,传到handler就没值了 赋值的代码 new Thread(n ...

  7. 如何查看自己运行ubuntu是32位还是64位

    当安装ubuntu在pc上,不推荐在32位pc安装64位操作系统,64位pc安装32位操作系统 方法/步骤 按ctrl+shift+t 快捷键,打开终端,输入sudo uname --m ,按下ent ...

  8. How to: Define a Windows Communication Foundation Service Contract

    This is the first of six tasks required to create a basic Windows Communication Foundation (WCF) app ...

  9. Asp.net性能优化技巧

    [摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Pe ...

  10. Oracle MySQL Server 拒绝服务漏洞

    漏洞名称: Oracle MySQL Server 拒绝服务漏洞 CNNVD编号: CNNVD-201401-316 发布时间: 2014-01-22 更新时间: 2014-01-22 危害等级: 中 ...