Java注解

是什么

  • 放在代码前面,用@表示的部分,是用来描述代码的元数据。
    • 什么是元数据
      • 简单来说:就是描述数据的数据,跟代码业务逻辑无关,在语法,配置层面保证代码的可用性和提供便利的配置方式。
      • 例子:

          她今年三十岁上下,个子高挑,身材匀称,黑黑的眉毛,红红的脸蛋。

          这句话提供了几个信息:年龄(三十岁上下)、身高(个子高挑)、相貌(身材匀称,黑黑的眉毛,红红的脸蛋)

          "年龄"、"身高"、"相貌" 就是元数据。

      • 好处:使信息的描述和分类实现格式化,从而为机器处理创造了可能。

怎么用

  • 一个使用是Java内置的注解
    • 用于代码检查
      • @Override 用于子类中标记重写的父类的方法,编译器会去检查父类中是否有这个方法,没有报错。
      • @Deprecated 用于标记过期不用的方法,编译器发现代码里面有使用该过期方法时,会发出警告。
      • @SuppressWarnings 用于抑制编译时的警告。
      • @FunctionInterface 用于标注某一个接口是函数式接口。如果不是函数式接口,编译器会报错。
      • 什么是函数式接口?
        • 接口里面只有一个抽象方法。
        • 接口可以被隐式的转换为lambda表达式
    • 对注解进行注解(元注解)
      • @Documented:让注解信息出现在 document 中
      • @Retention : 标记注解如何存储,支持以下三种参数 
        • RetentionPolicy.SOURCE : 注解只保留在源码中,编译时会忽略
        • RetentionPolicy.CLASS : 更高一级,编译时被编译器保留,但是运行时会被 JVM 忽略
        • RetentionPolicy.RUNTIME : 最高级,运行时会被保留,可以被运行时访问
      • @Target :标记注解作用于(修饰)什么对象,支持以下几种参数 
        • ElementType.TYPE : 作用于任何类、接口、枚举
        • ElementType.FIELD : 作用于一个域或者属性
        • ElementType.METHOD : 作用于一个方法
        • ElementType.PARAMTER : 作用于参数
        • ElementType.CONSTRUCTOR : 作用于构造函数
        • ElementType.LOCAL_VARIABLE : 作用于本地变量
        • ElementType. ANNOTATION_TYPE : 作用于注解
        • ElementType.PACKAGE : 作用于包
      • @Inherited 用于标记注解能否被继承。(如果父类添加了某个注解,而这个注解用@Inherited 进行了注解,那么其子类也将默认继承该注解)

 

  • 一个是自定义注解(需结合反射机制),基本步骤如下:
    • 通过@Interface定义注解并添加元注解信息(选择上面的四个元注解组合)
    • 将自定义注解用于代码中,并用反射机制定义注解处理类
    • 在main方法中执行检查

 

  • 代码实例
    • 定义注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
 * @Author:darrenqiao
 * */
@Retention(RetentionPolicy.RUNTIME) //存储到运行期
@Target(ElementType.FIELD)  //作用于字段
@Documented //可以被文档化
@Inherited //可以被注解的子类继承
//这里指定自定义注解的作用是检查值是在value为true时确保字段值仅为male和female中的一个
public @interface MyAnnotation {
    boolean value() default true;
}
    • 使用 和 处理注解
import java.lang.reflect.Field;

/*
 * @Author:darrenqiao
 * */

//定义使用自定义注解的类
class Person {
    
    @MyAnnotation(value = true)
    public String gender;

    public Person(String gender) {
        super();
        this.gender = gender;
    }
}

//通过反射实现对注解的处理
class CheckAnnotation {
    public static boolean check(Object object) throws IllegalArgumentException, IllegalAccessException {
        Field[] fields = object.getClass().getDeclaredFields();
        for(Field field : fields) {
            String gender = (String) field.get(object);
            return gender.equals("male") || gender.equals("female");
        }
        return false;
    }
}

public class AnnotationTest {
    
    public static void main(String[] args) throws Exception {
        Person p = new Person("male");
        //调用注解进行检查
        System.out.println(CheckAnnotation.check(p));
    }

}

 

posted @ 2018-06-17 00:08  darrenqiao  阅读(121)  评论(0编辑  收藏  举报