元注解

元注解是可以注解到注解上的注解,或者说元注解是一种基本注解,它能够应用到其它的注解上面。元注解有@Retention、@Documented、@Target、@Inherited、@Repeatable五种。

  • @Retention
    用于解释注解的的存活时间
    RetentionPolicy.SOURCE注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
    RetentionPolicy.CLASS注解只被保留到编译进行的时候,它并不会被加载到 JVM 中
    RetentionPolicy.RUNTIME注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们

  • @Documented
    顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去

  • @Target
    你可以这样理解,当一个注解被 @Target 注解时,这个注解就被限定了运用的场景
    ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
    ElementType.CONSTRUCTOR可以给构造方法进行注解
    ElementType.FIELD可以给属性进行注解
    ElementType.LOCAL_VARIABLE可以给局部变量进行注解
    ElementType.METHOD可以给方法进行注解
    ElementType.PACKAGE可以给一个包进行注解
    ElementType.PARAMETER可以给一个方法内的参数进行注解
    ElementType.TYPE可以给一个类型进行注解,比如类、接口、枚举

  • @Inherited
    B集成A,B就拥有了@Test注解

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
  • @Repeatable
    Repeatable 自然是可重复的意思。@Repeatable 是 Java 1.8 才加进来的,所以算是一个新的特性。
    举个例子,一个人他既是司机又是老师,同时他还是个父亲。
@interface Persons {
	Person[]  value();
}

@Repeatable(Persons.class)
@interface Person{
	String role default "";
}

@Person(role="teacher")
@Person(role="driver")
@Person(role="father")
public class SuperMan{
}

注解用法

// Jiecha.java
package ceshi;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Jiecha {

}

// NoBug.java
package ceshi;
import ceshi.Jiecha;


public class NoBug {
	
	@Jiecha
	public void suanShu(){
		System.out.println("1234567890");
	}
	@Jiecha
	public void jiafa(){
		System.out.println("1+1="+1+1);
	}
	@Jiecha
	public void jiefa(){
		System.out.println("1-1="+(1-1));
	}
	@Jiecha
	public void chengfa(){
		System.out.println("3 x 5="+ 3*5);
	}
	@Jiecha
	public void chufa(){
		System.out.println("6 / 0="+ 6 / 0);
	}
	
	public void ziwojieshao(){
		System.out.println("我写的程序没有 bug!");
	}

}

package ceshi;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


// TestTool.java
public class TestTool {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		NoBug testobj = new NoBug();
		
		Class clazz = testobj.getClass();
		
		Method[] method = clazz.getDeclaredMethods();
		//用来记录测试产生的 log 信息
		StringBuilder log = new StringBuilder();
		// 记录异常的次数
		int errornum = 0;
		
		for ( Method m: method ) {
			// 只有被 @Jiecha 标注过的方法才进行测试
			if ( m.isAnnotationPresent( Jiecha.class )) {
				try {
					m.setAccessible(true);
					m.invoke(testobj, null);
				
				} catch (Exception e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
					errornum++;
					log.append(m.getName());
					log.append(" ");
					log.append("has error:");
					log.append("\n\r  caused by ");
					//记录测试过程中,发生的异常的名称
					log.append(e.getCause().getClass().getSimpleName());
					log.append("\n\r");
					//记录测试过程中,发生的异常的具体信息
					log.append(e.getCause().getMessage());
					log.append("\n\r");
				} 
			}
		}
		
		
		log.append(clazz.getSimpleName());
		log.append(" has  ");
		log.append(errornum);
		log.append(" error.");
		
		// 生成测试报告
		System.out.println(log.toString());

	}

}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐