什么是注解
注解是 Java 代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。
通过使用注解,程序开发人员可以在不改变程序原有逻辑的情况下,在源代码中加入一些补充信息,代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证和部署。
注解的格式
注解前面有一个“@”符号
有以下三种形式:
- 不带参数的注解: @Annotation,
例如
@Override 限定重写父类方法 该注解只能用于方法;
@ Deprecated 表明这个方法已过时- 带一个参数的注解: @Annotation(参数),
例如
@SuppressWarnings(value=“unused”)。 //忽略未使用的变量的警告- 带多个参数的注解: @Annotiation({参数 1, 参数 2, 参数 3…}),
自定义注解
注解之所以强大,能被众多框架所使用,一个主要的原因就在于它允许程序员自定义注解。定义注解的语法形式和接口差不多,只是在 interface 前面多了一个@符号
自定义注解中的方法不带方法体
如果在注解里定义了成员变量,那么使用该注解时就应该为它的成员变量指定值
注解中的成员变量也可以有默认值,可使用 default 关键字。
代码格式如下:
// 定义一个简单的注解类型
public @interface Test {
}
例子如下:
public @interface MyTag {
// 定义带两个成员变量的注解
// 注解中的成员变量以方法的形式来定义
String name();
int age();
}
public class Test {
// 使用带成员变量的注解时,需要为成员变量赋值
@MyTag(name="linjialong", age=18)
public void info() {
...
}
...
}
public @interface MyTag {
// 定义带两个成员变量的注解
// 注解中的成员变量以方法的形式来定义
String name() default "linjialong";
int age() default 18;
}
public class Test {
// 使用带成员变量的注解时,需要为成员变量赋值
@MyTag
public void info() {
...
}
...
}
元注解
元注解是负责对其它注解进行说明的注解,自定义注解时可以使用元注解。Java 5 定义了 4 个注解
@Documented(会被 JavaDoc 工具提取成文档)
@Target(用来指定一个注解的使用范围)
@Target({ ElementType.METHOD })
public @interface MyTarget {
}
class Test {
@MyTarget
String name;
}
@Retention (描述注解的生命周期)
SOURCE:在源文件中有效(即源文件保留)
CLASS:在 class 文件中有效(即 class 保留)
RUNTIME:在运行时有效(即运行时保留)
@Inherited(指定该注解可以被继承)
@Target({ ElementType.TYPE })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInherited {
}
@MyInherited
public class TestA {
public static void main(String[] args) {
System.out.println(TestA.class.getAnnotation(MyInherited.class));
System.out.println(TestB.class.getAnnotation(MyInherited.class));
System.out.println(TestC.class.getAnnotation(MyInherited.class));
}
}
class TestB extends TestA {
}
class TestC extends TestB {
}
Java 8 增加了2个注解。
@Repeatable (允许在相同的程序元素中重复注解)
@Native (修饰成员变量,则表示这个变量可以被本地代码引用)
反射获取注解
当 @Retention 注解的属性 value 设置为 RetentionPolicy.RUNTIME 时,编译器将把注解记录在class 文件中,当运行 Java 程序时,虚拟机保留注解,程序可以通过反射获取该注解
在 SpringMVC 中,经常使用 @RequestMapping(value="") 注解,这样 Spring 就会将我们填写的
value 值当作路径存放在 map 结构中让我们访问。
@MyRequestMapping("/test")
public class TestController {
public void test() {
System.out.println("进入Test方法");
}
}
自定义 Person 注解
@Target({ ElementType.TYPE })
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Person {
String value();
}
@MyRequestMapping("/test")
@Person("C")
public class TestController {
public void test() {
System.out.println("进入Test方法");
}
}