HappyBKs教你写Java注解(1)——注解的分类、运行机制、做用域及概念汇总

注解这东西,已经在咱们的编程生活中习觉得常了。覆盖一个父类的方法,套用Spring、Mybatis中的编程套路,编写JUnit测试函数等等。你会发现,做为一个Java Coder,你无时无刻不在接触它们。java

可是如何编写一个属于本身的注解,或是但愿可以看懂那些NB框架的源代码,都有必要让你我去掌握编写自定义注解的方法。spring

本系列开始,我将和博客的观众们一块儿学习java注解的开发。编程


注解分类(按照来源来分)app

jdk中的注解:框架

@Override 重写父类的方法。若是父类没有该方法则编译报错ide

@Override
	public String toString() {
		return "Member [id=" + id + ", familyName=" + familyName
				+ ", givenName=" + givenName + ", salary=" + salary + "]";
	}

@Deprecated 之前的定义的类或方法,你们正用得high,你却以为好像这样设计并很差,因而加入了新的类或方法来代替它们。可是,这样作,之前的小伙伴们又要抱怨了,"你这个先后版本不兼容"云云,因此咱们须要用一个注解指明"存在但已过期,可用但不推荐”,这就是@Deprecated。函数

好比,因为如今的猫都不捉老鼠了,因此,下面这个方法,我决定废弃。可是之前已经有太多围绕猫的方法调用了,因此我加入了注解@Deprecated。IDE中的删除线就是醒目的标识。工具

哎呀呀,好像调用注解了@Deprecated的方法以后,出现了warning!学习

HappyBKs我是个代码洁癖,必定要把这个警告去掉。测试

相似的咱们编写代码的过程当中,每每不可避免了会出现一些警告,有些咱们能够根据好的范式、好的习惯、好的经验把这些代码从新修改消除警告。可是有时一些场景,彷佛要求咱们包容他们。怎么办呢?这时候,能够用@SuppressWarnings注解,消除相应警告类型。

好比上面的调用废弃方法产生的警告,咱们能够改为这样:

如今警告没有了!: )


第三方注解: 

若是你是一个java框架的达人,必定知道spring额@Autowired自动创配,以及@Service和@Repository;也必定会用Mybatis的@InsertProvider,@UpdateProvider,@Option。

做为用框架的人,少不了和这些第三方注解打交道。这里就不介绍框架了。


自定义的注解:

若是咱们想读懂别人的代码、本身尝试着写一下框架、装装B格,那么本身写一个注解是必不可少的。这也是本系列文章的目标!!


其实要有一类比较特殊的注解,不知道该把它按照哪一个范畴进行划分,那就是元注解。

元注解:指的是注解的注解。就像元数据是描述数据的数据同样。具体的我会单独在一篇文章中介绍。


注解的运行机制、做用域、继承性等:

我门对注解进行分类,还能够按照运行机制分类

注解的运行机制:

按照这个运行机制的不一样,咱们能够将注解分红三类:

源码注解: 注解只在源码中存在,编译成.class文件就不存在了。

编译时注解:注解在.class文件里面存在。固然在.class文件中存在,在源码当中固然也是存在的。刚才说的3个jdk自带的注解@Deprecated 、@SuppressWarnings、@Override都属于编译时注解。也正由于如此,当你@Override了父类不存在的方法,编译时编译器会报错;调用@Deprecated的方法,编译器会警告。IDE才能在编辑代码时实时提示错误。

运行时注解:在运行阶段还起做用,甚至会影响运行逻辑的注解。

如何指定一个注解的运行机制:(即影响的时间点)

咱们在定义一个注解时,还须要指明它是源码注解、编译时注解仍是运行时注解。这里也须要用到一个枚举:

/*
 * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang.annotation;

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
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
}


注解的做用域:

注解的做用域指的是一个注解修饰的是什么语法单元。注解标识的是一个类,一个方法,一个域,一个构造器等等。这里在指定注解的做用域时会用到一个枚举来指定做用域的类型,这里我把jdk的源码列出:

package java.lang.annotation;

/**
 * A program element type.  The constants of this enumerated type
 * provide a simple classification of the declared elements in a
 * Java program.
 *
 * <p>These constants are used with the {@link Target} meta-annotation type
 * to specify where it is legal to use an annotation type.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

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

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}



注解的继承性:

规定了一个注解在标注了一个类、接口或方法等以后是否会在所在类的子类中生效。这个我会在本系列后面的文章中单独写一篇介绍。


注解输出到文档:

这个就是@Docmented注解,指定注解是否被输出到java文档中。

Documented 注解代表这个注解应该被 javadoc工具记录. 默认状况下,javadoc是不包括注解的. 但若是声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 因此注解类型信息也会被包括在生成的文档中。


具体如何写一个本身的注解。放到下一篇文章中写吧。

相关文章
相关标签/搜索