JAVA中自定义注解

最近几天在学习注解相关的知识点:

一、定义

   注解也叫作元数据,就是用来描述数据的数据。它其实就是程序代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取并执行相应的处理。注解主要是告诉编译器要做什么事情,在程序中可对任何程序元素进行注解。其可以声明在包、类。成员变量、成员方法、局部变量、方法参数等的前面,用来对这些程序元素进行说明、注释。

二、分类

   根据注解的作用可以分为基本注解、元注解(元数据注解)与自定义注解三种。

  基本注解:在JDK8的java.lang包中,java提供了5种基本注解,可以直接在程序代码中将其当做修饰符来使用,用于所支持的程序元素,其分别是@Deprecated,@Override,@SuppressWarnings @SafeVargs @Functionallnterface

 元注解:就是对注解进行标注的注解。java中定义了6种元注解类型:@Target @Retention @Document @Inherited @Repeatable和类型注解。

@Target用来限制注解的使用范围,即指定该注解可用于哪些程序元素

@Retention用于说明注解的保存范围,保存范围使用枚举类型java.lang.annotation.RetentionPolicy来指定其保留策略值。

@Document用于指定被修饰的注解可被javadoc.exe工具提取成文档。

@Inherited用于描述一个父类的注解可以被子类继承。

@Repeatable用于开发重复注解。

三、自定义注解,其过程主要包括三个步骤:

1、定义注解,使用@interface进行声明,其实就是继承了java.lang.annotation.Annotation接口.

 注解的成员由未实现的方法组成,其中的成员变量以无参数方法的形式来声明,就变量名后面必须有圆括号()

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 * 定义一个testannotation
 */
@Target(ElementType.FIELD)//使用在成员变量上
@Retention(RetentionPolicy.RUNTIME)//在程序执行时生效
@Documented
public @interface TestAnnotation {
  String description() default "";
}

 

2、解析注解,原理是利用反射来获取注解以及其对应的值

import java.lang.reflect.Field;
/*
 * 注解解析
 */
public class TestAnnotationParse {
    public static String getDescription(Class<?> clazz,int key){
       Field[] fields = clazz.getDeclaredFields();
       Field f=null;
       for(Field field:fields){
           //将此对象的accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消Java语言访问检查。
      //值为 false 则指示反射的对象应该实施 Java 语言访问检查。

           field.setAccessible(true);
           try {
               //判断是否存在注解,且注解的值跟入参一致
              if(field.isAnnotationPresent(TestAnnotation.class)&&
                       Integer.valueOf(field.get(clazz).toString())==key){
                      f=field;
                      break;
               }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
       }
       if(f!=null)
           //获取变量上注解的值
         return f.getAnnotation(TestAnnotation.class).description();
       
       return null;
    }
    
    
    public static void main(String[] args) {
        System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, 200));
        System.out.println(TestAnnotationParse.getDescription(TestAnnotationObject.class, TestAnnotationObject.RET_CODE_FAIL));
    }
}

3、使用注解

/*
 * 使用自定义的注解
 */
public class TestAnnotationObject {
 @TestAnnotation(description="success")
  public static int RET_CODE_SUCC=200;
 
 @TestAnnotation(description="fail")
 public static int RET_CODE_FAIL=201;

}

 

在以上步骤的第二步中,需要用到反射获取注解,而且要用获取字段信息的方法来获取被注解的字段,

这时候有个困惑,getDeclaredFields与getFields有什么区别?

区别:

getDeclaredFields:获得某个类的所有声明的字段,包括private 、protected、public,但是不包括父类声明的字段;

getFields:获得某个类的所有的公共字段(public),包括父类;

同样类似的还有

getConstructors()和getDeclaredConstructors()、

getMethods()和getDeclaredMethods(),

这两者分别表示获取某个类的构造方法和成员方法。

 

以上记录下来,以防忘记。

posted @ 2017-07-25 18:46  sunshine_coast  阅读(278)  评论(0编辑  收藏  举报