Java基础教程——解析注解

解析注解

Java 5开始,java.lang.reflect包下的反射API可以在运行时读取Annotation。

应用:定义一个自动执行方法的注解,解析注解、通过反射执行方法,替代配置文件。

package ah.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//==============================================
//注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface AutoMethod {
	String className();
	String methodName();
}
// ==============================================
// 想要调用的类和方法
class Cat {
	public void show() {
		System.out.println("Cat show");
	}
}
// ==============================================
// 测试类
@AutoMethod(className = "ah.annotation.Cat", methodName = "show")
public class TestParseAnn {
	public static void main(String[] args) {
		// 1.获取类的字节码对象
		Class<TestParseAnn> cls = TestParseAnn.class;
		// 2.获取注解对象
		AutoMethod ann = cls.getAnnotation(AutoMethod.class);
		// 3.调用注解对象的抽象方法,获取返回值
		String className = ann.className();
		String methodName = ann.methodName();
		System.out.println("获取到类名:" + className);
		System.out.println("获取到方法名:" + methodName);
		// 使用反射集合调用方法(略)
	}
}
获取到类名:ah.annotation.Cat
获取到方法名:show

例:使用注解进行方法测试

注解传入的变量:B
方法public static void ah.AnnoTestExample.m3(java.lang.String)运行失败,异常:java.lang.IllegalArgumentException: 参数出错!
注解传入的变量:御弟
--m1--:御弟
共运行了:2个方法,其中:
失败了:1个,
成功了:1个!

package ah.annotation;
import java.lang.annotation.*;
import java.lang.reflect.Method;
//============================================
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
@interface AnnoTest {
	// 注解的属性:
	String name() default "御弟";
}
// ============================================
// 使用自定义注解的类
class AnnoTestExample {
	@AnnoTest
	public static void m1(String _name) {
		System.out.println("--m1--:" + _name);
	}
	public static void m2() {
		System.out.println("这个方法不测试");
	}
	@AnnoTest(name = "B")
	public static void m3(String _name) {
		if (_name.equals("B")) {
			throw new IllegalArgumentException("参数出错!");
		} else {
			System.out.println("--m3--:" + _name);
		}
	}
}
// ============================================
// APT:Annotation Processor Test(注解处理工具)
class APT {
	public static void process(String className) throws ClassNotFoundException {
		int passed = 0;
		int failed = 0;
		Class<?> _class = Class.forName(className);
		for (Method m : _class.getMethods()) {
			// 如果该方法使用了@注解
			if (m.isAnnotationPresent(AnnoTest.class)) {
				// 获取注解中的变量
				AnnoTest ann = m.getAnnotation(AnnoTest.class);
				String name = ann.name();
				System.out.println(" 注解传入的变量:" + name);
				try {
					// 调用m方法
					m.invoke(_class, name);
					// *方法无参数可直接传入null:
					// m.invoke(null);
					// 测试成功,passed计数器加1
					passed++;
				} catch (Exception ex) {
					System.out.println("方法" + m + "运行失败,异常:" + ex.getCause());
					// 测试出现异常,failed计数器加1
					failed++;
				}
			}
		}
		// 统计测试结果
		System.out.println("共运行了:" + (passed + failed) + "个方法,其中:
" + "失败了:"
				+ failed + "个,
" + "成功了:" + passed + "个!");
	}
}
/**
 * 测试类,主方法
 */
public class TestMyAnnotation {
	public static void main(String[] args) throws ClassNotFoundException {
		String _包类名 = "ah.annotation.AnnoTestExample";
		APT.process(_包类名);
	}
}
 注解传入的变量:B
方法public static void ah.annotation.AnnoTestExample.m3(java.lang.String)运行失败,异常:java.lang.IllegalArgumentException: 参数出错!
 注解传入的变量:御弟
--m1--:御弟
共运行了:2个方法,其中:
失败了:1个,
成功了:1个!
原文地址:https://www.cnblogs.com/tigerlion/p/11182854.html