概述

Annotation是JDK 5.0以后提供对元数据的支持,可以在编译、加载和运行时被读取,并执行相应的处理。所谓Annotation就是提供了一种为程序元素设置元数据的方法,可用于修饰包、类、构造器、方法、成员变量、参数和局部变量的声明,这些信息被存储在Annotation的“name=value”对中。

Annotation能被用来为程序元素设置元数据,比如一段代码的作者或者告诉编译器禁止一些特殊的错误,不会影响代码的执行。

使用Annotation时要在其前面增加【@】符号,并把该Annotation当作一个修饰符使用,用于修饰它支持的程序元素。

定义一个Annotation类型使用【@interface】关键字,定义一个Annotation类型与定义一个接口非常像(只是多了一个@符号)。
public @interface TestAnnotation {
}

注解的属性

Annotation可以是上面的简单形式,还可以包含成员变量。
Annotation的成员变量以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和类型。
使用带有属性的Annotation时,必须为其属性指定值,否则会报错。

定义Annotation时可以使用【default】关键字为属性设置默认值,使用时可以不为该属性指定值(此时使用默认值)。
如果Annotation中具有名为【value】的属性,在使用时如果只使用value属性的话,可以不写属性名直接指定值。
Annotation的属性类型只能是基本类型、String、Enum、Class及上述类型的一维数组类型。

public class Test {
    @UserInfo(password = "123456", value = "这里不能省略")
    public static void main(String[] args) {
    }
}
@interface UserInfo {
    String username() default "bqt";
    String password();
    String value();
}

public class Test {
    @UserInfo({ "这里", "可以", "省略", "呵呵" })
    public static void main(String[] args) {
    }
}
@interface UserInfo {
    String username() default "bqt";
    String[] value();
}

4个元注解

元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明。
Java5.0定义的元注解:
  • @Target
  • @Retention
  • @Documented
  • @Inherited
这些类型和它们所支持的类在java.lang.annotation包中可以找到。


@Target注解

@Target修饰普通的Annotation,指定该Annotation可以用于修饰哪些程序单元,例如方法、成员变量等。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
@Target注解包含一个ElementType类型的value属性,该属性值只能是如下几个:
  • ANNOTATION_TYPE 注释类型声明
  • CONSTRUCTOR 构造方法声明
  • FIELD 字段声明(包括枚举常量)
  • LOCAL_VARIABLE 局部变量声明
  • METHOD 方法声明
  • PACKAGE 包声明
  • PARAMETER 参数声明
  • TYPE 类、接口(包括注释类型)或枚举声明
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}
public enum ElementType {
    TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE

}


@Retention注解

@Retention修饰普通Annotation,用于指定Annotation的生命周期。
@Retention包含一个RetentionPolicy类型的value属性,该属性值只能是如下几个:
  • CLASS:编译器将把Annotation记录在class文件中。当运行Java程序时,JVM不可获取Annotation信息。
  • RUNTIME:编译器将把Annotation记录在class文件中。当运行Java程序时,JVM也可以获取Annotation信息,程序可以通过反射获取该Annotation信息。
  • SOURCE:Annotation只保留在源代码中,编译器直接丢弃这种Annotation。
简单来说,就是
  • SOURCE:在源文件中有效
  • CLASS:在class文件中有效
  • RUNTIME:在运行时有效
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}
public enum RetentionPolicy {
    SOURCE, CLASS, RUNTIME
}

@Documented和@Inherited注解

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

@Inherited也是一个标记注解,阐述了某个被标注的类型是被继承的。
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
注意:@Inherited类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。
当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

3个基本的注解

在java.lang包中提供了3个基本Annotation的用法,可以通过查看API文档来了解。

1、@Override:限定重写父类方法。值得注意的是,@Override只能修饰方法,不能修饰其他程序元素。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

2、@Deprecated:标示已过时,用于表示某个程序元素已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

3、@SuppressWarnings:抑制编译器警告,表示被该Annotation修饰的代码取消显示指定的编译器警告。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

获取注解信息

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    // 属性
    String name();
    String[] jobs();
    String addr() default "广州";
}

public class Person {
    @MyAnno(jobs = { "码农", "架构师" }, name = "白乾涛")
    public int age = 26;

    @MyAnno(jobs = "工作", name = "包青天")
    private void fun() {
        System.out.println("方法");
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
        //1 获取对应类的Class类对象
        Class<Person> clazz = Person.class;
        //2 根据Class类对象获取Method或Field
        Field field = clazz.getField("age");
        Method method = clazz.getDeclaredMethod("fun");
        //3 通过Class类对象、Metod对象、Field对象,获取对应的注解信息.
        MyAnno myAnno1 = field.getAnnotation(MyAnno.class);
        MyAnno myAnno2 = method.getAnnotation(MyAnno.class);

        System.out.println(Arrays.toString(myAnno1.jobs()));
        System.out.println(myAnno2.name());
    }
}

Annotation注解的更多相关文章

  1. Java Annotation 注解

    java_notation.html div.oembedall-githubrepos { border: 1px solid #DDD; list-style-type: none; margin ...

  2. Hibernate的Annotation注解

    当项目变得比较大的时候,如何还使用hbm.xml文件来配置Hibernate实体就会变得比较复杂.这里Hibernate提供了Annotation注解方式,使得Hibernate的映射文件变得很方便管 ...

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

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

  4. paip.Java Annotation注解的作用and 使用

    paip.Java Annotation注解的作用and 使用 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog. ...

  5. hibernate annotation注解方式来处理映射关系

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

  6. Android开发学习之路--Annotation注解简化view控件之初体验

    一般我们在写android Activity的时候总是会在onCreate方法中加上setContentView方法来加载layout,通过findViewById来实现控件的绑定,每次写这么多代码总 ...

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

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

  8. Annotation(注解)介绍

    Annotation(注解)是什么: Annotation(注解) 官方的定义:    An annotation is a form of metadata, that can be added t ...

  9. Hibernate 零配置之Annotation注解

    JPA规范推荐使用Annotation来管理实体类与数据表之间的映射关系,从而避免同时维护两份文件(Java 实体类 和 XML 映射文件),将映射信息(写在Annotation中)与实体类集中在一起 ...

  10. struts 多文件上传 annotation注解(零配置)+ ajaxfileupload + 异步 版本

    [本文简介] struts 多文件上传.基于”零配置“+"ajaxfileupload" 的一个简单例子. [导入依赖jar包] jquery-1.7.2.js : http:// ...

随机推荐

  1. JavaScript的“闭包”到底是什么

    在JavaScripot函数闭包的定义中,一般都有一个outer 函数,一个inner函数.那么“闭包”到底是指outer函数呢,还是指inner函数? 从官方定义来看,并不清楚:A closure  ...

  2. [PHP学习日志]简单Session的使用

    首先,给出一些Session的解释:目前最实用的网络协议即HTTP超文本传输协议,它是“无状态”的,所谓“无状态”是指它在用户与服务器交互时没有存储需要交互的“状态”.而Session 是在网络应用中 ...

  3. ASP.NET MVC的Action Filter

    一年前写了一篇短文ASP.NET MVC Action Filters,整理了Action Filter方面的资源,本篇文章详细的描述Action Filter.Action Filter作为一个可以 ...

  4. tomcat正常启动,但IP不能访问web。ping IP地址,一直超时。 用ipconfig命令修复TCP/IP的配置信息

    今天遇到一个好奇葩的问题  好吧是昨天遇到的一直没找到解决办法(`へ´) tomcat正常启动,但是通过IP不能访问web 用IP地址就是不行  (:′⌒`)  打不开 localhost就可以    ...

  5. codevs 1107 等价表达式

    传送门 题解:第一眼这题好像非常难得样子,简直没有思路.但是这可以用栈带入特殊值来解决.这里用到两个栈,一个是存贮数字,另一个存贮运算符,按优先级进行运算.当读入的运算符比运算符栈的栈顶元素优先级低时 ...

  6. reaver使用相关

    (非TP-LINK路由推荐–d9 –t9参数防止路由僵死 reaver -i mon0 -b MAC -a -S –d9 –t9 -vv) 小结-学习时应因状况调整参数(-c后面都已目标频道为1作为例 ...

  7. nutch fetcher.server.delay

    1 配置因素 <property>  <name>fetcher.server.delay</name>  <value>0.0</value&g ...

  8. Steps

    uva846:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  9. 常用SNS开源系统比较

    常用SNS开源系统比较 这 几天看了很多关于SNS(社交网络服务) 的东西..得到了不少启发..目前的IDEA是..可以在学校弄一个试试..主打的东西不能和现有的SNS冲突(如校内网).利用本地优势. ...

  10. HDOJ(HDU) 2097 Sky数(进制)

    Problem Description Sky从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=2 ...