Java 注解
1. 基本语法
@interface { method declaration; }
定义注解与定义接口相似,主要有以下几点不同:
1. 定义注解需要在interface前加上@符号
2. 声明的方法没有参数
3. 声明的方法不能抛出异常
4. 方法的返回值仅限于基本数据类型、String、Class、enum、annotation、以及前面几种数据类型的数组
5. 声明方法时可以指定默认返回值。注:方法不能有不确定的值,也就是说要么具有默认值,要么使用的时候提供值
2. 元注解
元注解是专门负责注解其它注解:
@Target 表示该注解可以用于什么地方,。可能的ElementType参数:
CONSTRUCTOR:构造器的声明
FIELD:域的声明
LOCAL_VARIABLE:局部变量的声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存该注释信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢掉。
CLASS:注解在class文件中可用,但会被JVM丢弃。
RUNTIME:JVM将在运行期也保留注解,因此可以通过反射机制读取注解中的信息。@Documented 将此注解包含在Javadoc中 @Inherited 允许子类继承父类中的注解。
3. 内置的注解
Java SE5内置了三种,定义在java.lang中的注解:
@Override,表示当前的方法定义将覆盖父类中的方法。
@Deprecated,如果程序中使用了注解为它的元素,那么编译器会发出警告。
@SuppressWarnings,关闭不当的编译器警告信息。
4. 自定义注解
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) public @interface Developer { String value(); }
5. 标记注解
没有方法或元素的注解称为标记注解
public @interface MarkerAnnotation {}
6. 单值注解
只有一个方法或元素的注解称为单值注解
public @interface SingleAnnotation { String value() default ""; }
7. 如何解析注解
package com.inspur.demo.ThinkInJava20; 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) public @interface Developer { String value(); }
package com.inspur.demo.ThinkInJava20; public class BuildHouse { @Developer("Alice") public void aliceMethod() { System.out.println("This method is written by Alice"); } @Developer("Popeye") public void buildHouse() { System.out.println("This method is written by Popeye"); } }
package com.inspur.demo.ThinkInJava20; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class TestAnnotation { public static void main(String args[]) throws SecurityException, ClassNotFoundException { for (Method method : Class.forName("com.inspur.demo.ThinkInJava20.BuildHouse").getMethods()) { if (method.isAnnotationPresent(Developer.class)) { for (Annotation anno : method.getDeclaredAnnotations()) { System.out.println("Annotation in Method '" + method + "' : " + anno); Developer a = method.getAnnotation(Developer.class); if("Popeye".equals(a.value())){ System.out.println("Popeye the sailor man! " + method); } } } } } }