@Target
表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention
表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
注:注解的可用的类型包括以下几种:所有基本类型、String、Class、enum、Annotation、以上类型的数组形式。元素不能有不确定的值,即要么有默认值,要么在使用注解的时候提供元素的值。而且元素不能使用null作为默认值。注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略“value=”,直接写需要的值即可。
例子
/**
* <p>
*
*
* 测试注解类
* </p>
* @date 2018年9月6日 下午6:19:31
* @version
*/
public class AnnotationTest {
@Test
public static void m1() {
}
@Test
public static void m2() {
throw new RuntimeException();
}
@Test
public void m3() {
}
public void m4() {
}
@ExceptionTest({IndexOutOfBoundsException.class})//NullPointerException.class,
public void m5() {
String str = null;
System.out.println(str.length());
}
public static void main(String[] args) {
String className = "cn.liu.hui.peng.annotation_custom.AnnotationTest";
int testCount = 0;
int errorCount = 0;
try {
Class<?> c = Class.forName(className);
Method[] methods = c.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isAnnotationPresent(Test.class)) {
testCount ++;
try {
methods[i].invoke(new AnnotationTest());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
errorCount ++;
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("testCount : " + testCount + " errorCount : " + errorCount);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
}