Java注解
Java注解在开发中有很多用途,比如spring框架和mybatis中的注解配置,通过Java反射机制在运行期获取Java类的注解信息,我们也可以自定义注解,在自定义注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法。
元注解
元注解的作用就是负责注解其他注解,也就是注解的注解,Java5.0在java.lang.annotation包下定义了4个标准的meta-annotation类型,这些注解信息可以在编译期使用预编译工具处理,也可以在运行期使用Java反射机制进行处理。Java5.0定义的元注解:
- Documented
- Inherited
- Retention
- Target
@Documented
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化
@Inherited
表示子类可以继承父类中的该注解。
@Retention
定义注解的保留策略
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
value的类型是RetentionPolicy,RetentionPolicy是一个枚举类型
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
- RetentionPolicy.SOURCE:表示注解将在编译期间被丢弃
- RetentionPolicy.CLASS:表示注解将通过编译记录在class文件中,但运行期间不可用,如果没有指定策略则使用该策略。
- RetentionPolicy.RUNTIME:表示注解将通过编译记录在class文件中,并且运行期间可用,可以通过反射机制获取注解。
@Target
定义注解的作用目标。换句话说就是定义该注解可以用在Java的哪些元素上。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
value的类型是ElementType[],ElementType也是一个枚举类型
public enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE
}
可以选择自己需要的一个或多个,其中TYPE目标是指类、接口、枚举或注解;ANNOTATION_TYPE目标是ANNOTATION,类似于@Target和@Retention。
内置的Java注解
Java带有三个内置的注释,这些注释用于给出Java编译期指令。这些注释是:
- @Deprecated
- @Override
- @SuppressWarnings
@SuppressWarnings
该注解使得编译器可以抑制给定方法的警告。例如,如果某个方法调用了不推荐的方法或者进行了不安全的类型转换,编译器会生成警告,你可以通过注解包含要压制的警告。
public class Annot {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
Map map = new HashMap();
map.put("1", "a");
}
}
SuppressWarnings注解有一个属性String[] value,上述的注解可以用于类或方法上压制警告。
@Override
该@Override注解用于覆盖超类中的方法,如果该方法与超类中的方法不匹配,编译器会给你一个错误。该注解不是必要的,但使用它会校验你是否重写了父类的方法,这也是我们最常用的注解,无需过多解释。
@Deprecated
该@Deprecated注解被用于弃用标记类、方法或字段,这意味着它不应该再被使用。当你使用被弃用的类、方法或字段时,编译器会给您一个警告。比如String类中的getBytes(int srcBegin,int srcEnd,byte[] dst,int dstBegin)方法使用了@Deprecated注解,表示该方法已过时。
自定义注解
当注解只有一个属性时,按照惯例一般命名该属性名为value,当使用该注解时可以省略属性名称,如
@SuppressWarnings(value={ "rawtypes", "unchecked" })
@SuppressWarnings({ "rawtypes", "unchecked" })
自定义注解示例:
@Documented
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
String name();
int age();
String[] newNames();
}
@interface关键字表示这是一个注解类,与Class、Interface理解类似。使用注解时必须给所有的属性赋值:
@MyAnnotation(
value = "1",
name="Jakob",
age=37,
newNames={"Jenkov", "Peterson"})
public class TestAnnotation {
}
默认值
从上述代码中可以发现,每次使用注解的时候都需要对其属性赋值,我们可不可以只赋值我们需要的属性呢?我们可以在自定义注解类中为属性设置默认值。
public @interface MyAnnotation {
String value() default "";
String name();
int age();
String[] newNames() default {};
}
这样我们在使用注解的时候,可以在不需要指定value和newNames属性的情况下使用默认值,当然你也可以为每个属性都设置一个默认值。
@MyAnnotation(
name="Jakob",
age=37)
public class TestAnnotation {
}