5.1java中的注解

分类

  1. 由编译器使用的注解:此类注解不会进入.class文件,被编译后就被扔掉了(SOURCE)
    - @Override:让编译器检查该方法是否正确地实现了覆写;
    - @SuppressWarnings:告诉编译器忽略此处代码产生的警告。
  2. 由工具处理.class文件使用的注解:这类注解一般不会自己处理,而是一些工具自动加载(CLASS)
  3. 最常用的注解:在程序运行期间能够读取的注解,加载后存在在JVM中。(RUNTIME)
    根据以上分类,因此我们经常使用的将是RUNTIME类型的注,并且学习的也是。
    大部分注解会有一些配置参数:最常用的是value,如果配置参数不填,则为默认值。
    如果参数名称是value,且只有一个参数,那么可以省略参数名称。

定义注解:

在java中我们可以自己定义注解,格式如下:

  1. 第一步,用@interface定义注解
  2. 第二步,添加参数、默认值(最常用的参数定义为value)
  3. 第三步,用元注解配置注解

定义注解@Report

public @interface Report {
    int type() default 0;//注解的参数,类似于无参方法,default设置默认值
    String level() default "info";
    String value() default "";
}

元注解:可以修饰其他注解的注解叫做元注解
java中已经定义了一些元注解,通常我们只需要使用而不需要去编写。

  • @Target:在定义注解时添加,它可以将注解定义在用于源码的那些位置:
    - 类或接口:ElementType.TYPE;
    - 字段:ElementType.FIELD;
    - 方法:ElementType.METHOD;
    - 构造方法:ElementType.CONSTRUCTOR;
    - 方法参数:ElementType.PARAMETER。

    @Target(ElementType.METHOD)//定义注解@Report可用在方法中
    public @interface Report {
        int type() default 0;
        String level() default "info";
        String value() default "";
    }
    
  • @Retention:定义了注解的生命周期,若不定义则默认class阶段
    - 仅编译期:RetentionPolicy.SOURCE;
    - 仅class文件:RetentionPolicy.CLASS;
    - 运行期:RetentionPolicy.RUNTIME。

    @Retention(RetentionPolicy.RUNTIME)
    public @interface Report {
        int type() default 0;
        String level() default "info";
        String value() default "";
    }
    
  • @Repeatable:可以定义注解(Annotation)是否可重复
    最终注解可以如下:

    @Report(type=1, level="debug")
    @Report(type=2, level="warning")
    public class Hello {
    }
    
  • @Inherited:定义子类是否可以继承父类定义的注解。(只针对@Target为类或接口类型有效)

使用反射读取注解:

所有的注解都继承自java.lang.annotation.Annotation,因此,读取注解,需要使用反射API。
方法包括:
判断注解是否存在类、字段、方法或是构造方法中:

  • Class.isAnnotationPresent(Class) (类)
  • Field.isAnnotationPresent(Class) (字段)
  • Method.isAnnotationPresent(Class) (方法)
  • Constructor.isAnnotationPresent(Class) (构造方法)
    例如,判断@Report是否存在Person类中
Person.class.isAnnotationPresent(Report.class);

利用反射读取注解值

  • Class.getAnnotation(Class)
  • Field.getAnnotation(Class)
  • Method.getAnnotation(Class)
  • Constructor.getAnnotation(Class)
    例:
// 获取Person定义的@Report注解:
if (cls.isAnnotationPresent(Report.class)) {
	Report report = Person.class.getAnnotation(Report.class);
}
int type = report.type();
String level = report.level();

利用反射读取注解可能会有空值返回因此,在获取值之前要先判断。

注解使用

注解如何使用,由程序自己决定。
该注解定义一个字段的规则

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Range {
    int min() default 0;
    int max() default 255;
}
public class Person {
    @Range(min=1, max=20)
    public String name;

    @Range(max=10)
    public String city;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值