zoukankan      html  css  js  c++  java
  • 【JAVA

      注解在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注解的简单介绍,希望对大家有帮助~~

  • 相关阅读:
    Codeforces Round #692
    【kuangbin专题一】简单搜索
    B. Beam Cannon【2014上海邀请赛】
    E. Maze【2014上海邀请赛】
    策略模式 Strategy -- 学习HeadFirst设计模式记录
    状态模式 State -- 学习HeadFirst设计模式记录
    迭代器模式 Iterator,组合模式 Composite -- 学习HeadFirst设计模式记录
    命令模式 Command – 学习HeadFirst设计模式记录
    单例模式Singleton – 学习HeadFirst设计模式记录
    工厂模式Factory – 学习HeadFirst设计模式记录
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6229464.html
Copyright © 2011-2022 走看看