zoukankan      html  css  js  c++  java
  • java

    Annotation元数据(一)

    一、Annotation究竟是什么?

    是java5.0中的新特征

    数据的数据(元数据)

    Annotation和访问修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。

    信息以“name=value”方式保存

    annotation类型是一种接口,通过java反射方式进行访问。

    二、Annotation涉及的概念?

    annotation:

    是java5.0中新增的语法,它的行为十分类似public、final这样的修饰符

    annotation类型 :

    annotation类型定义了annotation的名字、类型、成员默认值。

    一个annotation类型是一个特殊的java接口,

    annotation成员(是一个特殊的方法):

    annotation的成员在annotation类型中以无参数的方法的形式被声明。

    可以有默认值(使用default关键字)

    marker annotation类型:

    没有任何成员。

    三、Java5.0中的标准Annotation

    Override:

    java.lang.Override是一个marker annotation类型,它被用作标注方法。

    作用:说明了被标注的方法重载了父类的方法

    使用场合:这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时发挥威力。

    Deprecated:

    是一个marker annotation

    作用: 用于标记已过期或不赞成使用的元素(如方法)

    SuppressWarnings:

    @SuppressWarnings被用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告。

    serial

    @SuppressWarnings("deprecation")

    @SuppressWarnings(" unchecked ")

    @Target 修饰的目标,是类、方法、字段

    @Retention 保留时间,编译、运行

    四、自定义Annotation语法

    Public @interface 名称{

    Public 类型  成员1() [default 默认值];

    Public 类型  成员2() [default 默认值];

    Public 类型  成员3() [default 默认值];

    }

    返回类型

    可以是基本数据类型,数组和字符串

    不可以是日期类型

    自定义Annotation语法

    /**

     * 表示Column是实现了java.lang.annotation.Annotation接口的一个类

     * 注释类与接口的区别

     * 1) interface @interface

     * 2)  注释的方法可带默认值

     * 3) 指定Retention 在程序运行时仍然存在

     * 4)  指定Target 主要修饰方法

     */

    @Retention(RetentionPolicy.RUNTIME)

    @Target(ElementType.METHOD)

    public @interface Column

     {

    public String name();  //返回数据库表的字段名

    public int len() default 20;   //返回字段长度

    public boolean unique(); //是否可空

    }

    例子1:自定义一个最简单的Annotation——IfInvoke 

    package com.aptech.servlet;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    @Retention(RetentionPolicy.RUNTIME)

    public @interface IfInvoke {

    public boolean invoke();

    }

    注意:

    @Retention(RetentionPolicy.RUNTIME):表示在运行时元数据还能被访问

    @interface:相当于实现了Annotation接口

    Invoke:不需要实现的方法,并且返回类型有比较大的限制

    例子2:自定义一个最简单的Annotation——Employee(1)

    Employee类的基本结构

    package com.aptech.servlet;

    import (导入略)

    public class Employee {

    @IfInvoke(invoke = true)

    public void extraSalary(){

    System.out.println("雇员是业务员,业务提成是:3000元");

    }

    }注意:

    @IfInvoke(invoke = true):相当于invoke方法的返回值为true

    调用代码:

    Employee emp = new Employee();

        try {

        Method m = emp.getClass().getMethod("extraSalary", new Class[]{});

        Annotation[] as = m.getAnnotations();

        for(Annotation a : as){

        if(a instanceof IfInvoke){

        IfInvoke ii = (IfInvoke)a;

        boolean b = ii.invoke();

        if(b){

        m.invoke(emp, new Object[]{});

        }else{

        System.out.println("不是业务员,不被调用");

        }

        }

        }

        } catch (Exception e1) {

        e1.printStackTrace();

        }

    五、Annotation类型的annotation

    Annotation类型可以被它们自己所标注。

    Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明。

    这些类型和它们所支持的类在java.lang.annotation包中可以找到,主要有以下几个:

    Target

    Retention

    Documented

    六、Target类型

    Target

    描述了annotation所修饰的程序成员的类型 。

    Target类型有唯一的value作为成员。这个成员的类型是ElementType[]类型的,ElementType类型是可以被标注的程序成员的枚举类型。

    ElementType类型定义如下:

    public enum ElementType {

      TYPE,    // Class, interface, or enum (but not annotation)

      FIELD,  // Field (including enumerated values)

      METHOD,    // Method (does not include constructors)

      PARAMETER,    // Method parameter

      CONSTRUCTOR,// Constructor

      LOCAL_VARIABLE,// Local variable or catch clause

      ANNOTATION_TYPE,// Annotation Types (meta-annotations)

      PACKAGE   // Java package

    }

    七、Retention 类型

    Retention描述了annotation是否被编译器丢弃或者保留在class文件中。

    通常有几种不同的选项:

    将注释保留在编译后的类文件中,并在第一次加载类时读取它。

    将注释保留在编译后的类文件中,但是在运行时忽略它。

    按照规定使用注释,但是并不将它保留到编译后的类文件中。

    这三种选项用 java.lang.annotation.RetentionPolicy 枚举表示 。

    public enum RetentionPolicy {

      SOURCE,// Annotation is discarded by the compiler

      CLASS,// Annotation is stored in the class file, but ignored by the VM

      RUNTIME// Annotation is stored in the class file and read by the VM

    }

    默认情况下,annotation被保存在class文件中,但在运行时并不能被反射访问。 ( RetentionPolicy. CLASS )

    八、Documented类型

    Documented 是一个标记注释 。

    Documented 表示注释应该出现在类的Javadoc 中。

    例如

    在IfInvoke注释类型中,按如下定义:

    @Retention(RetentionPolicy.RUNTIME)

    public @interface IfInvoke {

    public boolean invoke();

    }

    Employee类的extraSalary()方法生成的注释如下:

    public void extraSalary() [和普通没什么两样]

    如果改成如下的定义方式:

    @Documented

    @Retention(RetentionPolicy.RUNTIME) //表示在运行时元数据还能被访问

    public @interface IfInvoke {

    public boolean invoke();

    }

    Employee类的extraSalary()方法生成的注释如下:

    @IfInvoke(invoke=true)

    public void extraSalary()

    也就是说,javadoc工具会将Annotation抽取出并添加到HTML文件中

    一个稍微复杂的示例

    有一个注释类型如下:

    public @interface ComplexAnnotation {

    public enum Sex{男, 女};

    public String[] love();//爱好

    public Sex sex() default Sex.女;//性别

    public String name();//姓名

    public int age();//年龄

    }

    问题:

    请将该注释类型补充完整。

    将该注释类型注释某一个类,赋值后将值读取出来并打印在Console,参考结果如下:

    李赞红

    25

    游泳  爬山

    import java.lang.annotation.Annotation;

    @AnnotationDmo(Loves ={"爬山","游泳"} ,

                         sex= AnnotationDmo.Sex.男,

                         age = 25,name="李赞红")

    public class App {

           /**

            * @param args

            */

          

          

           public static void main(String[] args) {

                  // TODO Auto-generated method stub

                  Class cl=App.class;

                  AnnotationDmo[] ann=(AnnotationDmo[])cl.getAnnotations();

                  for(AnnotationDmo a:ann){

                         if(a instanceof AnnotationDmo){

                                AnnotationDmo an =(AnnotationDmo)a;

                                System.out.println(an.name());

                                System.out.println(an.age());

                                System.out.println(an.sex());

                                System.out.println(an.sex());String Loves= "";

                                for(String s : an.Loves()){

                                Loves += s + "  ";

                                }

                                System.out.println(Loves);

                         }

                  }

           }

    }

    思考:

    注释类型中的成员可以有返回值,通过default关键字定义。

    成员返回值类型不可以为java.util.Date或包装类等类型,可以是String或基本数据类型。

    成员返回值类型可以是枚举类型。注意枚举类型的定义方法和访问方法。

    访问方法:ComplexAnnotation.Sex.男


     

  • 相关阅读:
    d3.js了解
    java常用验证码
    连接数据库的配置文件
    MD5加密的使用
    ssm下载文件
    Ajax基于rest风格上传图片
    web常见页面错误整理
    前后端一起用cookie来保存密码
    通用mapper插件
    ssm的maven依赖,直接复制可以使用
  • 原文地址:https://www.cnblogs.com/BlogNetSpace/p/1525391.html
Copyright © 2011-2022 走看看