在java中合理使用注解是代码优雅的重要方式,使用注解在代码的可读性上会有所降低(对于初中级开发会导致一些阅读障碍),但是在代码的整洁和精简来说是非常有优势的。
注解只是filter的一种实现方式,创建注解看起来和接口类似:@interface,注解就是接口,只是是一种比较特殊的接口。
下面我们来看一个简单的注解示例:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {
String[] authority();
}
这里有两个重要的注解@Target
,这个是使用注解的目标对象ElementType说明当前注解可以在哪些场景下使用,ElementType的源码如下:
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 /* 类、接口(包括注释类型)或枚举的使用声明 */
}
另外一个主要注解就是@Retention
声明作用域,指定当前定于的注解在什么时候生效。定于枚举是RetentionPolicy,源码如下:
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE, /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了 */
/**
* 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, /* 编译器将Annotation存储于类对应的.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 /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}
如果一个注解声明作用域是SOURCE
,则意味着只在代码的编译处理期生效,过后则不再起作用的。典型的如@override
就是在编译时校验是否有重载,校验完后不在具有其他作用。CLASS
则意味着会执行在class文件中,只是不由JVM读入,CLASS
是注解的默认行为,如果不定义@Retention
则默认会是CLASS
。RUNTIME
是表示会存储于class文件,并且由JVM读入。
每个注解都会和一个RetentionPolicy
关联,每个注解都会和一个以上的ElementType
关联。
一般比较常用的注解如:
@Deprecated 所标注内容,不再被建议使用。
@Override 只能标注方法,表示该方法覆盖父类中的方法。
@Documented 所标注内容,可以出现在javadoc中。
@Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。
@Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
@SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
在spring中也有很多实用注解:
@Controller
@Service
@Component
@RequestMapping
@RequestParam
@RequestBody
@Param
......
特别是在springboot中表现就更加明显了,很多原本需要复杂配置的内容都通过注解可以很简单就实现。
建议更深入了解注解。