注解是附加在代码中的一些元信息,可以对字段、方法以及类进行说明或配置。一些编译工具或者Java虚拟器可以载编译期或者运行时根据 注解来动态的编译或者执行代码。
1、元注解:
元注解是指注解的注解,包括@Retention、@Target、@Document、@Inherited四种。
@Retention :定义注解的保留策略,取值如下:
@Retention(RetentionPolicy.SOURCE):注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS):默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME):注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target :定义注解的作用目标,取值如下:
@Target(ElementType.TYPE):作用于类、接口、枚举
@Target(ElementType.FIELD):作用于字段
@Target(ElementType.METHOD):作用于方法
@Target(ElementType.PARAMETER):作用于方法参数
@Target(ElementType.CONSTRUCTOR):作用于构造函数
@Target(ElementType.LOCAL_VARIABLE):作用于局部字段(方法内部定义的字段)
@Target(ElementType.ANNOTATION_TYPE):作用于注解
@Target(ElementType.PACKAGE):作用于包
@Document :说明该注解将被包含在Java Doc中。当使用java的导出doc的命令式定义了该注解的注解将会包含在Java Doc中
@Inherited :定义该注解可以被继承。子类可以继承父类中定义了该注解的注解。
2、自定义注解:
1、元注解:
元注解是指注解的注解,包括@Retention、@Target、@Document、@Inherited四种。
@Retention :定义注解的保留策略,取值如下:
@Retention(RetentionPolicy.SOURCE):注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS):默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.RUNTIME):注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target :定义注解的作用目标,取值如下:
@Target(ElementType.TYPE):作用于类、接口、枚举
@Target(ElementType.FIELD):作用于字段
@Target(ElementType.METHOD):作用于方法
@Target(ElementType.PARAMETER):作用于方法参数
@Target(ElementType.CONSTRUCTOR):作用于构造函数
@Target(ElementType.LOCAL_VARIABLE):作用于局部字段(方法内部定义的字段)
@Target(ElementType.ANNOTATION_TYPE):作用于注解
@Target(ElementType.PACKAGE):作用于包
@Document :说明该注解将被包含在Java Doc中。当使用java的导出doc的命令式定义了该注解的注解将会包含在Java Doc中
@Inherited :定义该注解可以被继承。子类可以继承父类中定义了该注解的注解。
2、自定义注解:
不带属性的注解:
示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Get {
}
使用:
@Get
public class SignupRequest{
}
带有属性的注解:
示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Path {
public String path();
}
使用:
@Path(path="VisitorRegister.ashx")
public class SignupRequest{
}
说明:
当只有一个属性,属性名称又是value的时候,在使用时属性名可以省略不写,例如:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Path {
public String value();
}
@Path("VisitorRegister.ashx")
public class SignupRequest{
}
当有多个属性时,多个属性的定义使用英文逗号(,)隔开,并且即使属性名称是value也不能省略不写
示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Path {
public String value();
public int count();
}
使用:
@Path(value = "nihao", count = 0)
public class BaiduRequest{
}
属性还可以定义默认值,定义了默认值的属性在使用注解时可以不写此属性:
示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Path {
public String value();
public int count() default 100;
}
使用:
@Path("nihao")
public class BaiduRequest{
}
属性的类型可以是byte、byte[]、short、short[]、int、int[]、long、long[]、float、float[]、double、double[]、char、char[]、boolean、boolean[]、String、String[] enum、Anntation之一。
3、解析注解:
获取到注解之后直接调用方法即可获取相应的参数
示例:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Host {
public String port();
public String value();
}
@Host(port="123", value = "sfs")
public class User {
}
public class Test {
public static void main(String... strings){
Host host = User.class.getAnnotation(Host.class);
System.out.println(host.port());
System.out.println(host.value());
}
}
第二种当然就是反射了。具体怎么用在这里就不说了。