一 有时候需要自定义注解,java给了我们是四个元注解(定义注解的注解):
1 Target:用来表示直接所修饰的对象范围
它的可用范围(ElementType取值有:constructor构造方法、field作用域成员变量、method方法、local_variable局部变量、package包、parameter参数、type类 接口或enum声明、annotation_type用于注解)
2 Retention:定义该注解被保留时间长短
它的取值有:
source:在源文件有效,编译器直接丢弃注解
class:在class文件有效
runtime:在运行时有效
3 documented:被该注解修饰的注解类将被javadoc工具提取成文档
4 inherited:被它修饰的注解具有继承性
二 下面通过元注解来自定义注解实现一个单元测试工具
1 先定义四个注解类:
//Test注解类:被修饰的方法会执行
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
//Before注解类:在@Test修饰的方法执行前执行
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Before {
}
//After注解类:在@Test修饰的方法执行后执行
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface After {
}
//Ignore注解类:被修饰的方法不会执行
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Ignore {
}
2 定义注解解析器:对类里面的方法上的注解进行解析
public class MyJuit {
public static void run(Class c) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
Object o=c.newInstance();
List<Method> testList=new ArrayList<Method>();
List<Method> beforeList=new ArrayList<Method>();
List<Method> afterList=new ArrayList<Method>();
Method [] method=c.getDeclaredMethods();
for(Method m:method){
if(m.isAnnotationPresent(Test.class)){
testList.add(m);
}
if(m.isAnnotationPresent(Ignore.class)){
continue;
}
if(m.isAnnotationPresent(Before.class)){
beforeList.add(m);
}
if(m.isAnnotationPresent(After.class)){
afterList.add(m);
}
}
//通过反射 执行@Test修饰的方法
for(Method s:testList){
//如果存在@Before修饰的方法,那么优先执行
if(beforeList!=null){
for(Method b:beforeList){
b.invoke(o,null);
}
}
s.invoke(o,null);
}
//执行@After修饰的方法
for(Method m:afterList){
m.invoke(o,null);
}
}
}
3 创建测试类:
public class total {
@Before
public void before(){
System.out.println("这是前置操作");
}
@After
public void after(){
System.out.println("这是后置方法");
}
@Test
public void test(){
System.out.println("这是测试方法");
}
@Before
public void before2(){
System.out.println("这也是前置操作方法");
}
@Ignore
public void ignore(){
System.out.println("这是忽略的方法");
}
public static void main(String []args){
try {
MyJuit.run(total.class);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4 运行结果:
这也是前置操作方法
这是前置操作
这是测试方法
这是后置方法