Java注解

注解简介,使用

英语Annotation,又被称为注释类型
是一种引用数据类型,编译之后也是.class文件

与注释的区别

注释是给程序员看的
注解是是给程序看的(@Override,@WebServlet等)

注解的目标

类(如@RestController),方法(如@Override),变量(如@Autowired)

注解的作用

其实注解就是一种给程序看的参考,或者一种标记。

注解标记的类/方法/变量上有/无这个注解,可以有两种处理方式

注解的组成部分

元注解+[修饰符列表] @interface 注解类型名+注解中定义属性

 // 1. 元注解
//@Target注解用来标注,被标注的注解可以出现在哪些位置上
@Target(ElementType.METHOD)//表示被标注的注解只能标记在方法上
//@Retention用来标注,被标注的注解最终保存在什么位置上
@Retention(RntentionPolicy.SOURCE)//表示注解属性值的可见性只停留在java源文件当中
//还有RntentionPolicy.CLASS:表示该注解被保存在class文件中,但是不能被反射获取属性值
//RntentionPolicy.RUNTIME:表示该注解被保存在class文件中,并且可以被反射机制所读取属性值

// 2. [修饰符列表] @interface 注解类型名
 public @interface MyAnnotation{
 // 3. 注解中定义属性
    String name();
    String color();
    int age() default 23;
 }

注解的类型

1. 元注解

如果一个注解用来修饰另外一个注解,那么这个注解被称为元注解(注解注解的注解叫做元注解)

从JDK 1.5开始, Java增加了对元数据(MetaData)的支持,提供了4个标准的用来对注解类型进行注解的注解类,我们称之为 meta-annotation(元注解)

@Target 描述注解的使用范围(即:被修饰的注解可以用在什么地方)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE, // 类

    /** Field declaration (includes enum constants) */
    FIELD,// 变量

    /** Method declaration */
    METHOD,// 方法

    /** Formal parameter declaration */
    PARAMETER,//参数

    /** Constructor declaration */
    CONSTRUCTOR,//构造器

    /** Local variable declaration */
    LOCAL_VARIABLE,// 本地

    /** Annotation type declaration */
    ANNOTATION_TYPE,// 其他注解

    /** Package declaration */
    PACKAGE,// 包

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Target注解至少选一个,可以多选(因为属性是一个数组)

@Rentention 描述注解的生命周期(即:被修饰的注解被保留到何时)

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

从上面的代码我们可以发现,@Retention是三选一

@Documented 会被javadoc工具动态提取成文档。

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

@Inherited 允许子类继承父类中的注解。

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

2. JDK自带的注解

//关于java.lang下的注解
@Deprecated//表示不鼓励程序员使用的程序元素,通常是因为它很危险或者有更好的选择
@Override
//JDK5.0新特性
//表示重写,只能注解方法,是给编译器参考的,运行阶段没有关系。
//属于标识性注解,编译器会自动检查,如果不是重写父类的方法,编译器报错
@SupperessWarnings//

@Deprecated(Since = “9”)//表示JDK9之后就过时了

  • 标注的方法在非本类的main方法里面调用的时候,会被标注删除线
  • 运行之后,在message里面会传递警告消息,表示已经过

注解中定义属性

如果一个注解当中有属性,调用的时候必须给该属性指定属性值,除非该属性有默认值

属性的类型可以是:

byte,short,int,long,float,double,boolean,char,String,Class,枚举类型

以及以上每一种类型的数组形式

当是数组的时候需要用大括号{}赋值,如果数组当中只有一个元素,大括号可以省略

/**
 * 在注解当中可以定义属性,被此注解注解的类必须为此属性赋值
 * 看着像一个方法
 * 如果一个注解当中有属性,
 * 调用的时候必须给该属性指定默认值,除非该属性有默认值
 * @return
 */
public @interface MyAnnotation {

    String name();
    String color();
    int age() default 23;//属性指定默认值
}

@MyAnnotation(name = "zxk",color = "blue")//age有默认值,所以不需要写出来

特殊情况value属性

//如果属性名为value,并且只有一个属性的时候,可以省略属性名和等于号不写
//属性值需要用反射机制去拿
public @interface Myannotation {
    String value();
}

实例

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {

    String[] value();
}
@MyAnnotation("/ToRun")
public class ToRun {
    @MyAnnotation("/a")
    private int a;

	@MyAnnotation("/run")
    public void run() {

    }

    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = Class.forName("org.leetCode.officialCode.annotation.ToRun");

        MyAnnotation myAnnotation = (MyAnnotation) clazz.getDeclaredAnnotation(MyAnnotation.class);

        System.out.println(myAnnotation.value()[0]);
    }
}

在这里插入图片描述

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值