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

  • 相关阅读:
    PostgreSQL中的partition-wise join
    Partition-wise join
    外观模式 门面模式 Facade 结构型 设计模式(十三)
    桥接模式 桥梁模式 bridge 结构型 设计模式(十二)
    组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)
    创建型设计模式对比总结 设计模式(八)
    原型模式 prototype 创建型 设计模式(七)
    单例模式 创建型 设计模式(六)
    建造者模式 生成器模式 创建型 设计模式(五)
    抽象工厂模式 创建型 设计模式(四)
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6229464.html
Copyright © 2011-2022 走看看