1、注解概述
注解Annotation是从JDK5.0引入的;
注解的作用:1、注解不是程序本身,注解是对程序做解释说明作用; 2、注解是给编译器看的,(注解信息处理流程是最重要的)。
注解的定义格式:
public @interface MyAnnotation{
//数据类型 参数名(); //注意参数名后面有括号,但不代表这是方法
}
注解的使用格式:在pakage、class、method和field上使用 @注解名(属性赋值),例如:@SuppressWannings(value="all")
2、内置注解
我们先认识一下JDK中的常见的内置注解:
2.1 @Override
@Override:该注解的意思是重写,这用在子类重写父类的方法上,表明该方法是父类存在的方法,如果使用了该注解的方法在父类中并不存在,那么就会报错。这个注解中没有参数,表明这是一个标识性注解。如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
2.2 @Deprecated
@Deprecated:该注解的意思是过时的,JDK中很多已经过时的方法会使用该注解,标识了这个注解的方法不建议我们使用。
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
2.3 @SuppressWarnings
@SuppressWarnings:该注解的意思压制警告,我们在写有些代码的时候,编译器会给警告,代码下方会画黄色波浪线。如果想不显示的话,就可以使用该注解,让代码看起来更加清爽。
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
它与前两个注解不同的是:它有一个value参数,所以在使用的时候必须设置参数的值,参数可选值如下:
参数值 | 解释 |
deprecation | 使用了过时的类或方法的警告 |
unchecked | 执行了未检查的转换时的警告,如使用集合时未指定泛型 |
fallthrough | 当在使用switch语句时法生case穿透 |
path | 在类路径、源文件路径等中有不存在的路径的警告 |
serial | 当在可序列化的类上缺少serialVersionUID定时的警告 |
finally | 任何finally语句不能完成时的警告 |
all | 以上所有情况的警告 |
使用示例:
@SuppressWarnings("all")
public class AnnotationTest {
@Override
public String toString() {
Date date = new Date();
return null;
}
}
3、自定义注解
使用@interface自定义注解,自动继承了 java.lang.annotation.Annotation接口。
注意:
1、可以通过default来给参数设置默认值;
2、如果只有一个参数,一般参数名称设置为 value。
3.1 元注解
在自定义注解之前,我们先来学习一下元注解。从之前的@Override等注解的定义可以看出,每个注解的声明都使用其他的两个注解:@Target和@Retention。其实还有两个元注解:@Documented和@Inherited,用的比较少,这里不讨论。
3.1.1 @Target元注解
作用:用于描述注解的使用范围,即注解可以用在什么地方,比如方法、类等。定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
它的可取值是在枚举类 ElementType 中定义的,有:TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,ANNOTATION_TYPE、PACKAGE 共8个值。
使用示例:该注解可以在类(接口)和方法上使用。
@Target(value={ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
}
3.1.2 @Retention
@Retention:表示需要在什么级别使用该注解,用于描述注解的声明周期。定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
它的参数值是枚举类:RetentionPolicy 中定义的,有三个值:SOURCE、CLASS和RUNTIME。
取值RetentionPolicy | 作用范围 |
SOURCE | 在源文件中有效(一般编译器和加载器使用) |
CLASS | 在calss文件中有效(一般编译器和加载器使用) |
RUNTIME | 在运行时有效,运行时有效,我们利用反射才能获取到,自定义注解一般设置为运行时有效。 |
使用示例:
@Target(value={ElementType.TYPE,ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)//运行时有效,反射可以获取到
public @interface MyAnnotation {
}
3.2 自定义完整注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value={ElementType.TYPE,ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)//运行时有效,反射可以获取到
public @interface MyAnnotation {
String className() default "";
int age() default 0;
String[] schools() default {"清华","北大"};
}
自定义了一个注解,里面有3个参数,并且都使用default给了默认值。
自定义注解的使用:
public class AnnotationTest {
@MyAnnotation(className="精英班级",age=100,schools={"师大","博才"})
public void test(){
}
}
注意:如果没有给注解的参数指定默认值,那么在使用的时候就必须给每个参数都赋值,否则会报错。如果注解只有一个参数,并且参数名称是value,那么在指定参数的时候,可以直接写参数值:@MyAnnotation("aaaa");
@Target(value={ElementType.TYPE,ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)//运行时有效,反射可以获取到
public @interface MyAnnotation2 {
String value();
}
使用时:
@MyAnnotation2("aaa")
public void test2(){
}