概念
Java注解是在JDK1.5时引入的新特性,由于很多流行框架中都使用过注解,因此掌握Java注解是对于Java工程师来说的一项必备技能。
本篇文章作为《Redis注解实现》专题的开篇,会介绍一些常见的注解,以及注解的使用语法等。

理解Java注解
public class Student {
//可以在一个方法上使用多个注解
@Deprecated //Java内置注解,用于标识方法过期不建议使用
@SuppressWarnings("uncheck") //忽略警告标识
public static void read() { }
@Test // 使用@Test注解修饰的方法
public void write(){ read(); }
}
@Test是测试框架中的一个注解,在方法上使用@Test注解,测试框架会自动识别该注解标识的方法,@Deprecated和@SuppressWarnings(“uncheck”) 是Java中内置的注解,并且也是我们经常用到的。
元注解与语法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
上面我们用到的@Target、@Retention称为元注解,元注解也就是注解的注解
@Target 元注解, 用于指定标记类型,ElementType.METHOD表示这个注解是被用于到方法上的。
@Retention() 元注解,用于指定注解的保留期是什么,保留期是什么意思呢?实际上上面代码中给定的参数RetentionPolicy.RUNTIME表示该注解用于运行时环境,也就是说这个注解只会在运行时环境中生效。
@interface这个关键字用于标识该类是一个注解类
@Target所有可用参数定义在枚举类ElementType中,具体如下:
public enum ElementType {
/** 类、接口(包括注释类型)或枚举声明 */
TYPE,
/** 字段声明(包括枚举常量) */
FIELD,
/** 方法声明 */
METHOD,
/** 参数声明 */
PARAMETER,
/** 构造函数声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 注释类型声明 */
ANNOTATION_TYPE,
/** 包声明 */
PACKAGE,
/** 类型参数声明,1.8版本新加入 */
TYPE_PARAMETER,
/** 类型的使用声明,1.8版本新加入 */
TYPE_USE
}
当@Target不指定任何属性时,表示适用于上面所有范围。@Target可以指定多个值,具体格式如下:
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
@Retention 元注解有三个值,分别是 ( source )源码级别、(class)类级别、(runtime)运行时,含义如下:
SOURCE:注解将被编译器丢弃(该类型的注解信息只会保留在源码里,源码经过编译后,注解信息会被丢弃,不会保留在编译好的class文件里)
CLASS:注解在class文件中可用,但会被VM丢弃(该类型的注解信息会保留在源码里和class文件里,在执行的时候,不会加载到虚拟机中),请注意,当注解未定义Retention值时,默认值是CLASS,如Java内置注解,@Override、@Deprecated、@SuppressWarnning等
RUNTIME:注解信息将在运行期(JVM)也保留,因此可以通过反射机制读取注解的信息(源码、class文件和执行的时候都有注解的信息),如SpringMvc中的@Controller、@Autowired、@RequestMapping等。
通过上面的@Test注解,我们简单了解了注解的的定义过程,不过@Test注解和自定义注解还是有一些区别的,由于@Test注解内部没有定义任何元素,一般称这样的注解为标记注解,下面我们看看自定义注解定义:
@Target(ElementType.TYPE)//只能应用于类上
@Retention(RetentionPolicy.RUNTIME)//保存到运行时
public @interface DBTable {
String name() default "";
}
我们定义了一个名为DBTable的注解,用于数据库表和Bean类的映射关系,与前面的@Test注解不同,@DBTable注解中我们声明了一个String类型的元素,给定默认值为空。
除了String类型的元素外,注解的声明中还支持下面几种类型:
所有基本数据类型(int,float,boolean,byte,double,char,long,short)
String
enum
Annotation
上述类型的数组
需要注意定义中不支持包装类,如果使用上述类型外的其他类型的话编译器会提示错误
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)
@interface Reference {
boolean next() default false;
}
@Target(ElementType.TYPE)//只能应用于类上
@Retention(RetentionPolicy.RUNTIME)//保存到运行时
public @interface DBTable {
//枚举类型
enum Status { FIXED, NORMAL }
//声明枚举
Status status() default Status.FIXED;
//布尔类型
boolean showSupport() default false;
//String类型
String name() default "";
//class类型
Class testCase() default Void.class;
//注解嵌套
Reference reference() default @Reference(next = true);
//数组类型
long[] value();
}
另外注解是不支持继承的,因此不能使用关键字extends来继承某个@interface,注解类编译之后,默认会自动继承Annotation接口。
注解中定义了名称为value的元素,如果该元素是唯一需要赋值的元素,可以直接在括号内给出元素的值,条件是元素名称必须是value
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBColumn {
String value() default "";
int size() default 3;
}
//使用注解
public class Test {
//当只想给value赋值时,可以使用以下方式
@DBColumn("age")
public int age;
//当size也需要赋值时必须采用key=value的方式赋值
@DBColumn(value = "MONEY",size = 2)
public int money;
}