Java注解

注解简介:

注解的主要作用有以下四方面:

  • 生成文档

  • 编译检查

  • 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。

  • 运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。

注解的分类:

内置注解

  • @Override,用于标明方法重写

  • @Deprecated,用于标明弃用的类或方法,如果使用了被@Deprecated注解的代码则编译器将发出警告

  • @SuppressWarnings,标明忽略警告,如@SuppressWarnings("rawtypes")(具体忽略警告类型略)

元注解

元注解是用于定义注解的注解,包括@Target@Retention@Documented@Inherited(JDK1.5)和@Repeatable@Native(JDK1.8):

  • @Target,用于标明注解使用的范围

  • @Retention,用于标明注解被保留的时间

  • @Documented,用于标明该注解会生成javadoc文档

  • @Inherited,用于标明注解会被继承

  • @Repeatable,重复注解

  • @Vative,用于标明成员变量可以被本地代码引用(通常适用于代码生成工具,以下不做详解)

自定义注解

可以根据自己的需求定义注解,并可用元注解对自定义注解进行注解。

元注解:

@Target

@Target注解,用于标明注解使用的范围

public enum ElementType {
    TYPE,   //类、接口、枚举类
    FIELD,  //成员变量(包括:枚举常量)
    METHOD, //成员方法
    PARAMETER,  //方法参数
    CONSTRUCTOR,    //构造方法
    LOCAL_VARIABLE, //局部变量
    ANNOTATION_TYPE,    //注解类
    PACKAGE,    //可用于修饰:包
    TYPE_PARAMETER, //类型参数,JDK 1.8 新增
    TYPE_USE    //使用类型的任何地方,JDK 1.8 新增
}

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

使用方法:

@Target(ElementType.METHOD) //单参数
​
@Target(value={TYPE, FIELD, METHOD})    //多参数
@Target({ElementType.TYPE,ElementType.METHOD})

@Retention

@Retention,用于标明注解被保留的时间

public enum RetentionPolicy {
    SOURCE, //源文件保留,(只在源码中保留)
    CLASS,  //编译期保留,默认值
    RUNTIME //运行期保留,可通过反射去获取注解信息
}

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

使用方法:

@Retention(RetentionPolicy.CLASS)

@Documented

@Documented,用于标明该注解会生成javadoc文档

使用方法:

@Documented

@Inherited

@Inherited,用于标明注解会被继承

使用方法:

@Inherited

@Repeatable

@Repeatable,重复注解,即允许在同一申明类型中(类,属性,或方法)多次使用同一个注解

源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    Class<? extends Annotation> value();
}

使用方法与样例:

@Repeatable(Authorities.class)
public @interface Authority {
     String role();
}

public @interface Authorities {
    Authority[] value();
}

public class RepeatAnnotationUseNewVersion {
    @Authority(role="Admin")
    @Authority(role="Manager")
    public void doSomeThing(){ }
}

注解与反射接口:

  • boolean isAnnotationPresent(Class<?extends Annotation> annotationClass)

判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false。注意:此方法会忽略注解对应的注解容器。

  • <T extends Annotation> T getAnnotation(Class<T> annotationClass)

返回该程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。

  • Annotation[] getAnnotations()

返回该程序元素上存在的所有注解,若没有注解,返回长度为0的数组。

  • <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)

返回该程序元素上存在的、指定类型的注解数组。没有注解对应类型的注解时,返回长度为0的数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。getAnnotationsByType方法与 getAnnotation的区别在于,getAnnotationsByType会检测注解对应的重复注解容器。若程序元素为类,当前类上找不到注解,且该注解为可继承的,则会去父类上检测对应的注解。

  • <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass)

返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释。如果没有注释直接存在于此元素上,则返回null

  • <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass)

返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释

  • Annotation[] getDeclaredAnnotations()

返回直接存在于此元素上的所有注解及注解对应的重复注解容器。

自定义接口:

定义接口

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface myAnnotation{
    public String name() default "";	//default 缺省为""
    public String content();
}

使用接口

@myAnnotation(name = "name",content = "lty")
    public String userAnnotation() {
        return "userAnnotation";
    }

使用反射获取接口(接口测试)

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class Main {

    @myAnnotation(name = "name",content = "lty")
    public String userAnnotation() {
        return "userAnnotation";
    }

    public static void main(String[] args) {
        try {
            // 获取所有methods
            Method[] methods = Main.class.getClassLoader()
                    .loadClass(("Main")).getMethods();

            // 遍历
            for (Method method : methods) {
                // 方法上是否有myAnnotation注解
                if (method.isAnnotationPresent(myAnnotation.class)) {
                    try {
                        // 获取并遍历方法上的所有注解
                        for (Annotation anno : method.getDeclaredAnnotations()) {
                            System.out.println("Annotation in Method '"
                                    + method + "' : " + anno);
                        }

                        // 获取myAnnotation对象信息
                        myAnnotation methodAnno = method
                                .getAnnotation(myAnnotation.class);

                        System.out.println(methodAnno.name());

                    } catch (Throwable ex) {
                        ex.printStackTrace();
                    }
                }
            }
        } catch (SecurityException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊雲浅谈天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值